由恐惧引起的泄漏
Leak caused by fread
我正在分析我编写的游戏的代码,我想知道每次执行以下代码片段时如何导致堆增加 4kb(我正在使用 Xcode 的堆快照分析进行分析):
u8 WorldManager::versionOfMap(FILE *file)
{
char magic[4];
u8 version;
fread(magic, 4, 1, file); <-- this is the line
fread(&version,1,1,file);
fseek(file, 0, SEEK_SET);
return version;
}
根据探查器,突出显示的行在每次调用函数时分配 4.00Kb 的内存,并带有一个malloc
,该内存永远不会释放。这似乎发生在其他调用fread
代码时,但这是最令人欣喜若狂的一次。
我错过了什么琐碎的东西吗?是我不应该关心的内部事情吗?
请注意:我正在iPhone上对其进行分析,并将其编译为发布版本(-O2
)。
如果你所描述的确实发生了,并且你的代码在其他地方没有错误,那么我认为这是实现中的一个错误。
我认为更有可能的是,您不关闭文件的可能性。 如果设备是非交互式的,则默认情况下,Stdio 流使用缓冲,并且在打开文件或执行 I/O 时分配缓冲区。 虽然只应分配一个缓冲区,但您肯定可以通过忘记关闭文件来泄漏缓冲区。 但可以肯定的是,关闭文件应该释放缓冲区。 不要忘记检查 fclose
返回的值。
假设为了论证您正确关闭了文件,您的代码中还有其他几个尼特不会导致此问题,但无论如何我都会提到。
首先,fread
调用读取一个具有一个大小为 4 的成员的对象。 您实际上有一个具有 4 个大小为 1 的成员的对象。 换句话说,交换要fread
的数字参数。 这仅在返回值的含义上有所不同(在部分读取的情况下很重要)。
其次,虽然您第一次调用fread
正确将char
的大小硬编码为 1(在 C 中,这是"size"的定义),但在风格上最好在第二次调用 fread
中使用 sizeof(u8)
。
如果这确实是内存泄漏的想法是正确的解释(并且其他地方没有任何错误),那么您可以通过关闭此特定文件的 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));
}
}
即使我们假设这确实是一个错误,并且泄漏是真实的,也非常值得将您的代码压缩为仍然演示问题的最小示例。 如果这样做揭示了真正的错误,你就赢了。 否则,您将需要最小的示例来报告实现中的错误。
- valgrind-hellgrind与泄漏检查的结果不同
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- Klocwork Inside的资源泄漏
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- C++功能泄漏内存,我是C++新手,不确定如何解决
- 瓦尔格林德的内存泄漏使用新的
- CPP 中的瓦尔格林德和记忆泄漏:"Conditional jump or move depends on uninitialised values"
- 由恐惧引起的泄漏