gpt4 book ai didi

c++ - 恐惧引起的泄漏

转载 作者:技术小花猫 更新时间:2023-10-29 11:07:10 24 4
gpt4 key购买 nike

我正在分析我编写的游戏代码,我想知道以下代码片段每次执行时如何导致堆增加 4kb(我正在使用 Xcode 的 Heapshot 分析进行分析):

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;
}

根据分析器,突出显示的行在每次调用函数时使用 malloc 分配 4.00Kb 的内存,该内存永远不会释放。这件事似乎发生在代码周围对 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));
}
}

即使我们假设这确实是一个错误,并且泄漏是真实的,也值得将您的代码压缩为仍然能证明问题的最小示例。如果这样做揭示了真正的错误,你就赢了。否则,您将需要最小示例来报告实现中的错误。

关于c++ - 恐惧引起的泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10155662/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com