двоичная ошибка чтения / записи во время выполнения - PullRequest
2 голосов
/ 04 марта 2010

Я смотрел на двоичные объекты чтения и записи в c ++, но у меня возникли некоторые проблемы. Это «работает», но кроме того, я получаю огромное количество ошибок / «информации».

То, что я сделал, это

Person p2;

std::fstream file;
file.open( filename.c_str(), std::ios::in | std::ios::out | std::ios::binary );
file.seekg(0, std::ios::beg );
file.read ( (char*)&p2, sizeof(p2));
file.close();
std::cout << "Name: " << p2.name;

Person - это простая структура, содержащая string name и int age. Когда я запускаю программу, она выводит «Имя: Боб», поскольку я уже создал программу для записи в файл (поэтому объект уже находится в имени файла).

ДОПОЛНИТЕЛЬНО к выводу имени, которое он также выводит:

* обнаружен glibc * программа: двойное освобождение от повреждения (fastttop): ***

Backtrace:

...

Карта памяти:

...

Прервать

Ответы [ 5 ]

3 голосов
/ 04 марта 2010

Является ли строка имени в структуре Person символьным массивом или строкой STL? Вы не можете заполнить строку STL путем двоичного чтения данных поверх нее, поскольку формат данных не сериализуем (содержит указатели)

1 голос
/ 04 марта 2010

Было бы интересно посмотреть, как вы записываете информацию в файл, а также как строится структура Person.
Если у вас нет проблем с тем, что файл представляет собой обычный текст, я бы предложил записать в файл, используя string::c_str() (который возвращает const char *), а также itoa() или itoa_s() для получения целого числа. как символ *.

Вы также можете иметь одного или нескольких конструкторов в Person:

Person(const std::string& name, int age);  
Person(const char* name, int age);

затем, когда вы извлекаете данные из файла, вы просто вызываете конструктор с этими данными.

0 голосов
/ 04 марта 2010

При использовании двоичного ввода-вывода размер должен быть фиксированным. Если вы используете строку STL здесь, это будет иметь проблему, так как размер строки STL является произвольным.

0 голосов
/ 04 марта 2010

Вы сказали, что записали объект Person в файл. Вы пытались использовать инструмент дампа, чтобы увидеть, что вы ожидаете увидеть внутри файла?

Также вы пытались вместо строки использовать обычный символ (как указывал @bdk)?

0 голосов
/ 04 марта 2010

Либо p2.name является символом *, и вы пишете и читаете значение указателя, а не то, на что оно указывает. Или p2.name - это более сложный тип, такой как std :: string, который использует внутренние указатели с той же проблемой.

Сериализация классов часто требует больше работы, чем просто выгрузка представления памяти.

...