如果您所描述的事情确实发生了并且您的代码在其他地方没有错误,我认为这是实现中的错误。
我认为更有可能是您没有关闭文件。如果设备是非交互式的,则 Stdio 流默认使用缓冲,并且在打开文件时或执行 I/O 时分配缓冲区。虽然只应分配一个缓冲区,但您肯定会因为忘记关闭文件而泄漏缓冲区。但当然,关闭文件应该释放缓冲区。不要忘记检查返回的值fclose
。
假设为了论证您正确地关闭了文件,您的代码中有几个其他的 nit 不会导致这个问题,但我还是会提到。
首先,您的fread
调用读取一个具有一个大小为 4 的成员的对象。您实际上有一个具有 4 个大小为 1 的成员的对象。换句话说,fread
交换了数字参数。这仅在返回值的含义上有所不同(在部分读取的情况下很重要)。
其次,虽然您第一次调用fread
正确地将大小硬编码char
为 1(在 C 中,即“大小”的定义),但sizeof(u8)
在第二次调用fread
.
如果这确实是内存泄漏的想法是正确的解释(并且其他地方没有任何错误),那么您可以通过关闭此特定文件的 stdio 缓冲来解决该问题:
bool WorldManager::versionOfMap(FILE *file, bool *is_first_file_io, u8 *version)
{
char magic[4];
bool ok = false;
if (*is_first_file_io)
{
// we ignore failure of this call
setvbuf(file, NULL, _IONBF, 0);
*is_first_file_io = false;
}
if (sizeof(magic) == fread(magic, 1, sizeof(magic), file)
&& 1 == fread(version, sizeof(*version), 1, file))
{
ok = true;
}
if (-1 == fseek(file, 0L, SEEK_SET))
{
return false;
}
else
{
return ok && 0 == memcmp(magic, EXPECTED_MAGIC, sizeof(magic));
}
}
即使我们假设这确实是一个错误,并且泄漏是真实的,也值得将您的代码压缩为仍然可以证明问题的最小示例。如果这样做揭示了真正的错误,你就赢了。否则,您将需要最小的示例来报告实现中的错误。