Ответ 1
Если то, что вы описываете, действительно происходит, и ваш код не имеет ошибок в другом месте, я думаю, что это ошибка в реализации.
Скорее всего, я думаю, что вы не закрываете файл. Потоки Stdio используют буферизацию по умолчанию, если устройство не является интерактивным, а буфер выделяется либо во время открытия файла, либо при выполнении ввода-вывода. Хотя нужно выделить только один буфер, вы можете, конечно, пропустить буфер, забыв закрыть файл. Но, конечно, закрытие файла должно освобождать буфер. Не забудьте проверить значение, возвращаемое fclose
.
Предположим ради аргумента, что вы правильно закрываете файл, в вашем коде есть еще несколько нит, которые не будут вызывать эту проблему, но я все равно упомянул.
Сначала ваш вызов 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));
}
}
Даже если мы идем с гипотезой о том, что это действительно ошибка, и утечка реальна, стоит сконцентрировать ваш код на наименьшем возможном примере, который все еще демонстрирует проблему. Если вы делаете это, обнаружите истинную ошибку, вы побеждаете. В противном случае вам понадобится минимальный пример, чтобы сообщить об ошибке в реализации.