あなたが説明していることが実際に起こっていて、コードに他の場所にバグがない場合、それは実装のバグだと思います。
おそらく、ファイルを閉じていない可能性が高いと思います。デバイスが非対話型の場合、Stdio ストリームはデフォルトでバッファリングを使用し、バッファはファイルが開かれたとき、または I/O が実行されたときに割り当てられます。バッファーは 1 つだけ割り当てる必要がありますが、ファイルを閉じるのを忘れると、バッファーが確実にリークする可能性があります。しかし、確かに、ファイルを閉じるとバッファが解放されます。によって返される値を確認することを忘れないでくださいfclose
。
ファイルを正しく閉じているという議論のために、コードにはこの問題を引き起こさないいくつかの他のニットがあると仮定しますが、とにかく言及します。
最初に、fread
呼び出しはサイズ 4 のメンバーを 1 つ持つオブジェクトを読み取ります。実際には、サイズ 1 のメンバーを 4 つ持つオブジェクトがあります。つまり、数値引数fread
が交換されます。これは、戻り値の意味のみが異なります (部分読み取りの場合は重要です)。
第 2 に、 への最初の呼び出しでfread
は のサイズが 1 として正しくハードコーディングされていますが (C では、これが「サイズ」の定義です)、 2 番目の への呼び出しでchar
使用する方がスタイル的にはおそらく優れています。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));
}
}
これが本当にバグであり、リークが本物であるという仮説を立てていたとしても、問題を示す可能な限り小さな例にコードを要約する価値は十分にあります。そうすることで真のバグが明らかになれば、あなたの勝ちです。それ以外の場合は、実装のバグを報告するための最小限の例が必要になります。