Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> непонятное содержимое массива после десериализации, %) 
V
    Опции темы
boostcoder
Дата 27.5.2012, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



привет.

сериализую массив 'long double'ов(исходный массив инициализирован целыми: 1,2,3,4,5,6) в текстовый архив. после десериализации, при выводе полученного массива на консоль, все отображается корректно.
проблема проявляется при сравнивании массивов с помощью memcmp(). при том, проблема проявилась только с текстовой сериализацей.

hex дамп исходного массива:
Цитата

0000000: 00 00 00 00 00 00 00 80 ff 3f 00 00 00 00 00 00   .........?......
0000016: 00 00 00 00 00 00 00 80 00 40 00 00 ff 7f 00 00   .........@......
0000032: 00 00 00 00 00 00 00 c0 00 40 00 00 ff 7f 00 00   .........@......
0000048: 00 00 00 00 00 00 00 80 01 40 00 00 ff 7f 00 00   .........@......
0000064: 00 00 00 00 00 00 00 a0 01 40 00 00 ff 7f 00 00   .........@......
0000080: 00 00 00 00 00 00 00 c0 01 40 00 00 00 00 00 00   .........@......
length: 96 bytes. CRC32: 0x8a940c74

hex дамп полученного массива:
Цитата

0000000: 00 00 00 00 00 00 00 80 ff 3f ff ff 00 00 00 00   .........?......
0000016: 00 00 00 00 00 00 00 80 00 40 00 00 ff 7f 00 00   .........@......
0000032: 00 00 00 00 00 00 00 c0 00 40 00 00 00 00 00 00   .........@......
0000048: 00 00 00 00 00 00 00 80 01 40 00 00 ff 7f 00 00   .........@......
0000064: 00 00 00 00 00 00 00 a0 01 40 64 f7 ff 7f 00 00   .........@d.....
0000080: 00 00 00 00 00 00 00 c0 01 40 ff ff ff 7f 00 00   .........@......
length: 96 bytes. CRC32: 0x4a3c2a42


что-то я даже не могу представить, почему это массивы содержат нужные значения, но при этом имеют разные дампы памяти smile 
подскажите из-за чего, и как лечить?

спасибо.


Это сообщение отредактировал(а) boostcoder - 27.5.2012, 21:31
PM WWW   Вверх
Alexeis
Дата 27.5.2012, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



long double случаем не 10ти байтовый? Может элементы выравнены на границу 4х байт и собственно отличаются мусором, которым забиваются байты выравнивания?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
boostcoder
Дата 27.5.2012, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(Alexeis @  27.5.2012,  21:45 Найти цитируемый пост)
long double случаем не 10ти байтовый?

проверяю на x86_64. тут sizeof(long double) == 16.

Цитата(Alexeis @  27.5.2012,  21:45 Найти цитируемый пост)
Может элементы выравнены на границу 4х байт и собственно отличаются мусором, которым забиваются байты выравнивания? 

эм.. может.
а как в этом убедится? как исправить?

PM WWW   Вверх
Alexeis
Дата 27.5.2012, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(boostcoder @  27.5.2012,  22:48 Найти цитируемый пост)
проверяю на x86_64. тут sizeof(long double) == 16.

  Скорее всего long double реально занимает 10 байт, потому что сопроцессор больше не умеет, а вот компилятор для оптимизации по скорости увеличил размер типа добавив лишних 6 байт, которые он не читает и не пишет и в сопроцессор они никак не попадают, поэтому могут содержать в себе что угодно. Проверить можно так. Сначала заполнить память заборчиком из бит 0xAA дает последовательность 01010101 , при помощи memset, а затем записать поверх заборчика полезные данные. После чего глянуть дамп. В каждом из блоков по 16 байт должны проглядываться фрагменты заборчика.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
boostcoder
Дата 27.5.2012, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(Alexeis @  27.5.2012,  22:06 Найти цитируемый пост)
long double реально занимает 10 байт

оно так на 32ух битной машине.
на 64ех битной  - равняется 16.
вот тому подтверждение: http://www.physics.uq.edu.au/people/foster...64_porting.html

Цитата(Alexeis @  27.5.2012,  22:06 Найти цитируемый пост)
Сначала заполнить память заборчиком из бит 0xAA дает последовательность 01010101 , при помощи memset, а затем записать поверх заборчика полезные данные. После чего глянуть дамп. В каждом из блоков по 16 байт должны проглядываться фрагменты заборчика. 

таки вариант smile
сейчас проверю...

Добавлено через 7 минут и 41 секунду
Цитата(boostcoder @  27.5.2012,  22:14 Найти цитируемый пост)
на 64ех битной  - равняется 16.

проверил еще и на венде. тоже 16.

PM WWW   Вверх
mes
Дата 27.5.2012, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.5.2012,  21:14 Найти цитируемый пост)
вот тому подтверждение: 

это не  мешает быть полезными толъко 10 битам из 16..


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.5.2012, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



хм..
без использования сериализации этот баг я немогу воспроизвести не на LWS, не на локальной машине smile 
код такой:
Код

#include <iostream>
#include <sstream>
#include <string>
#include <iterator>
#include <cstring>

/***************************************************************************/

int main() {
   constexpr size_t array_size = 6;
   long double lda1[array_size], lda2[array_size];

   std::ostringstream os;
   for ( size_t idx = 0; idx < array_size; ++idx ) {
      lda1[idx] = idx;
      os << lda1[idx] << ' ';
   }

   std::istringstream is(os.str());
   for ( size_t idx = 0; idx < array_size; ++idx ) {
      is >> lda2[idx];
   }

   std::cout << "lda1: ";
   std::copy(std::begin(lda1), std::end(lda1), std::ostream_iterator<long double>(std::cout, " "));
   std::cout << std::endl;
   std::cout << "lda2: ";
   std::copy(std::begin(lda2), std::end(lda2), std::ostream_iterator<long double>(std::cout, " "));
   std::cout << std::endl;

   bool ok = memcmp(&lda1[0], &lda2[0], sizeof(lda1[0])&array_size) == 0;
   std::cout << "arrays is " << (ok?"equal":"not equal") << std::endl;
}

/***************************************************************************/


http://liveworkspace.org/code/3f721237a32a...fceb2a1d2434115

а вот если std::ostringstream и std::istringstream заменить на типы сериализатора/десериализатора - то ошибка восспроизведется.

PM WWW   Вверх
borisbn
Дата 28.5.2012, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(boostcoder @  28.5.2012,  09:17 Найти цитируемый пост)
bool ok = memcmp(&lda1[0], &lda2[0], sizeof(lda1[0])&array_size) == 0;

если заменить на умножение, то получаем
Цитата
arrays is not equal

http://liveworkspace.org/code/78c1ff19c351...bbd7fb2fd099b7f

Добавлено через 3 минуты и 12 секунд
если long double заменить на long, то получаем equal.
Наверное проблема в переводе плавающих чисел в строку и обратно. например, для числа 1,5 вполне может не оказаться двоичного представления, и ближайшее к нему будет равно 1,4(9), однако, при переводе его в строку, мы получим 1,5


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 28.5.2012, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(boostcoder @  28.5.2012,  09:17 Найти цитируемый пост)
sizeof(lda1[0])&array_size

жуть какая smile 

Цитата(borisbn @  28.5.2012,  10:41 Найти цитируемый пост)
Наверное проблема в переводе плавающих чисел в строку и обратно. например, для числа 1,5 вполне может не оказаться двоичного представления, и ближайшее к нему будет равно 1,4(9)

я тоже так думаю. вот только не знаю. на сколько такое поведение правильно..
PM WWW   Вверх
mes
Дата 28.5.2012, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.5.2012,  20:29 Найти цитируемый пост)
что-то я даже не могу представить, почему это массивы содержат нужные значения, но при этом имеют разные дампы памяти  

 а чем десериализируете?

P.S. если вопрос о том могут ли равные значения бытьпредставлены разным набором битов, то ответ : могут smile




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.5.2012, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



исправленный код: http://liveworkspace.org/code/d57ddd3da320...88591407d374eac

Добавлено через 1 минуту и 13 секунд
Цитата(mes @  28.5.2012,  10:54 Найти цитируемый пост)
 а чем десериализируете?

этим.
PM WWW   Вверх
mes
Дата 28.5.2012, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  28.5.2012,  09:54 Найти цитируемый пост)
 вот только не знаю. на сколько такое поведение правильно.. 

для плавающих законно smile


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.5.2012, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



значит тест на сравнение байтового массива для таких типов некорректен?
PM WWW   Вверх
borisbn
Дата 28.5.2012, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



хммм. а ведь проблема именно в long double.
c float и с double - всё в порядке.
http://liveworkspace.org/code/d85ee8ad014c...4c3cfac76e72602
значит это
Цитата(borisbn @  28.5.2012,  10:41 Найти цитируемый пост)
Наверное проблема в переводе плавающих чисел в строку и обратно

не совсем верно


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 28.5.2012, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  28.5.2012,  11:09 Найти цитируемый пост)
проблема именно в long double.

выходит так..
так может вовсе запретить использование 'long double' ? или оставить на страх и риск юзеров?
PM WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0657 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.