Jac*_*ack 10 c++ xcode memory-leaks ios
我正在分析我编写的游戏的代码,我想知道以下代码段每次执行时如何有可能导致堆增加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;
}
Run Code Online (Sandbox Code Playgroud)
根据分析器,突出显示的行分配4.00Kb的内存,malloc每次调用该函数时,内存永不释放.这个问题似乎发生fread在代码周围的其他调用,但这是最令人讨厌的.
我有什么微不足道的错过吗?这是我不应该关心的内部事物吗?
就像一个注释:我在iPhone上进行分析,它被编译为release(-O2).
如果您所描述的情况确实发生并且您的代码在其他地方没有错误,那么我认为这是实现中的错误。
我认为更有可能的是您没有关闭文件。如果设备是非交互式的,Stdio 流默认使用缓冲,并且缓冲区在文件打开时或执行 I/O 时分配。虽然只应分配一个缓冲区,但您肯定会因忘记关闭文件而泄漏缓冲区。但当然,关闭文件应该释放缓冲区。不要忘记检查返回的值fclose。
假设为了论证您正确关闭了文件,您的代码中还有一些其他的问题,这些问题不会导致此问题,但无论如何我都会提到。
首先,您的fread调用读取一个具有 1 个大小为 4 的成员的对象。实际上,您有一个具有 4 个大小为 1 的成员的对象。换句话说,数字参数被fread交换。这仅在返回值的含义上有所不同(在部分读取的情况下很重要)。
其次,虽然您的第一次调用fread正确地硬编码了 as 1 的大小char(在 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));
}
}
Run Code Online (Sandbox Code Playgroud)
即使我们假设这确实是一个错误,并且泄漏是真实的,也非常值得将代码压缩为仍能证明问题的最小示例。如果这样做揭示了真正的错误,你就赢了。否则,您将需要最小的示例来报告实现中的错误。
| 归档时间: |
|
| 查看次数: |
854 次 |
| 最近记录: |