2009-08-11 3 views
1

У меня есть несколько функций, которые я создал некоторое время назад для чтения и записи std :: strings в FILE *, открытый для чтения в двоичном режиме. Они отлично работали раньше (и WriteString() все еще работает), но ReadString() продолжает давать мне ошибки повреждения памяти во время выполнения. Строки сохраняются путем записи их размера как unsigned int перед строковыми данными как char.Чтение std :: string из двоичного файла

bool WriteString(std::string t_str, FILE* t_fp) { 
// Does the file stream exist and is it valid? If not, return false. 
if (t_fp == NULL) return false; 
// Create char pointer from string. 
char* text = const_cast<char*>(t_str.c_str()); 
// Find the length of the string. 
unsigned int size = t_str.size(); 
// Write the string's size to the file. 
fwrite(&size, sizeof(unsigned int), 1, t_fp); 
// Followed by the string itself. 
fwrite(text, 1, size, t_fp); 
// Everything worked, so return true. 
return true; 

} 



std::string ReadString(FILE* t_fp) { 
// Does the file stream exist and is it valid? If not, return false. 
if (t_fp == NULL) return false; 
// Create new string object to store the retrieved text and to return to the calling function. 
std::string str; 
// Create a char pointer for temporary storage. 
char* text = new char; 
// UInt for storing the string's size. 
unsigned int size; 
// Read the size of the string from the file and store it in size. 
fread(&size, sizeof(unsigned int), 1, t_fp); 
// Read [size] number of characters from the string and store them in text. 
fread(text, 1, size, t_fp); 
// Store the contents of text in str. 
str = text; 
// Resize str to match the size else we get extra cruft (line endings methinks). 
str.resize(size); 
// Finally, return the string to the calling function. 
return str; 

} 

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

ответ

5

Самая большая проблема, которая выскочила на меня:

// Create a char pointer for temporary storage. 
char* text = new char; 
// ... 
// Read [size] number of characters from the string and store them in text. 
fread(text, 1, size, t_fp); 

Это создает текст как указатель на одного характера, а затем вы пытаетесь прочитать произвольное число символов (потенциально гораздо больше, чем один) внутрь. Для того, чтобы это работало правильно, вы должны создать текст в качестве массива символов после того, как вы выяснили, что размер был, как это:

// UInt for storing the string's size. 
unsigned int size; 
// Read the size of the string from the file and store it in size. 
fread(&size, sizeof(unsigned int), 1, t_fp); 
// Create a char pointer for temporary storage. 
char* text = new char[size]; 
// Read [size] number of characters from the string and store them in text. 
fread(text, 1, size, t_fp); 

Во-вторых, вы не освободить память, вы выделили текст. Вы должны сделать это:

// Free the temporary storage 
delete[] text; 

Наконец, есть хорошая причина, почему вы выбираете использовать файл C I/O в C++? Использование iostreams в стиле C++ облегчило бы все это и сделало бы ваш код намного, намного короче и удобочитаемым.

+0

Спасибо за ответ. Причина, по которой я использую C-файл IO, - это просто потому, что я изначально писал эти функции, когда был совершенно новым для C++, и я не совсем понял все вещи iostream. Я все еще использую эти функции только из-за какого-то старого кода, который их использует (который я намереваюсь вскоре заменить). –

2

Проблема заключается в том:

char* text = new char; 

вы выделения одного символа. Сделайте выделение после того, как вы знаете size, и выделите все необходимые вам size символы (например, с помощью new char[size]). (Во избежание утечки, конечно, после его копирования, конечно).

0

Извините, но выбранный ответ не работает для меня.

// UInt for storing the string's size. 
unsigned int size; 
// Read the size of the string from the file and store it in size. 
fread(&size, sizeof(unsigned int), 1, t_fp); 
// Create a char pointer for temporary storage. 
char* text = new char[size]; 
// Read [size] number of characters from the string and store them in text. 
fread(text, 1, size, t_fp); 

Размер заканчивается очень большим числом. Я что-то упускаю?

Смежные вопросы