根据Visual C ++运行时,在析构函数中调用free时会出现堆损坏。但我不明白为什么会有堆腐败,有人可以解释原因吗?确切的错误是:
CRT detected that the application wrote to memory after end of heap buffer.
另外,如果我忽略错误,程序不会崩溃,它会继续运行,当我按下一个键时,它会返回0。
该类只包含构造函数和析构函数以及私有变量FILE* target
和char* raw_data
。
foo::foo (wchar_t* path)
{
size_t size;
target = _wfopen (path, L"rb+");
if (!target) {
char* error = strerror (errno);
printf ("The file could not be opened: %s\n", error);
_exit (1);
}
fseek (target, 0L, SEEK_END);
size = ftell (target);
fseek (target, 0, SEEK_SET);
raw_data = (char*) malloc (size);
size = fread (raw_data, 1, size, target);
raw_data[size] = '\0';
}
foo::~foo ()
{
fclose (target);
free (raw_data);
}
int main ()
{
nbt* klas = new nbt (L"C:\\Users\\Ruben\\level");
puts ("Success?!");
delete klas;
getchar ();
return 0;
}
答案 0 :(得分:5)
在编写NUL
终止符时:
raw_data[size] = '\0';
...您使用的字节多于您分配的字节数。可能还有其他错误,但这一行肯定存在错误 - 写入未分配的内存是“未定义的行为”,可以解释您正在观察的崩溃。
答案 1 :(得分:4)
这个代码确实存在一个问题:
raw_data = (char*) malloc (size);
size = fread (raw_data, 1, size, target);
raw_data[size] = '\0';
您无法访问raw_data[size]
,因为它超出了分配的大小。 C / C ++中的索引访问是基于零的。因此,可以使用现有代码访问的raw_data
的最后一个元素是raw_data[size-1]
。为了能够将偏移size
的字节设置为零,您需要将malloc
更改为:
raw_data = (char*) malloc (size+1);
由于这是一个C ++应用程序,您可能希望使用流和new / delete而不是FILE指针和malloc / free。