Nếu những gì bạn mô tả thực sự đang diễn ra và mã của bạn không có lỗi ở nơi khác, đó là lỗi trong quá trình triển khai, tôi nghĩ vậy.
Nhiều khả năng tôi nghĩ, là khả năng bạn không đóng tệp. Luồng Stdio sử dụng bộ đệm theo mặc định nếu thiết bị không tương tác và bộ đệm được cấp phát vào lúc tệp được mở hoặc khi I/O được thực hiện. Trong khi chỉ có một bộ đệm nên được cấp phát, bạn chắc chắn có thể rò rỉ bộ đệm bằng cách quên đóng tệp. Nhưng chắc chắn, đóng tập tin nên giải phóng bộ đệm. Đừng quên kiểm tra giá trị được trả về bởi fclose
.
Giả sử vì lợi ích của đối số rằng bạn đóng đúng tệp có một vài phần tử khác trong mã của bạn sẽ không gây ra vấn đề này nhưng tôi sẽ đề cập đến.
Trước tiên, hãy gọi fread
cuộc gọi đọc đối tượng có một thành viên có kích thước 4. Bạn thực sự có một đối tượng có 4 thành viên có kích thước 1. Nói cách khác, đối số dạng số là fread
được hoán đổi. Điều này tạo ra sự khác biệt chỉ theo ý nghĩa của giá trị trả về (quan trọng trong trường hợp đọc một phần).
Thứ hai, trong khi cuộc gọi đầu tiên của bạn để fread
đúng cứng mã kích thước của char
như 1 (trong C, đó là định nghĩa về 'kích thước'), nó có thể là tốt hơn về phong cách sử dụng sizeof(u8)
trong cuộc gọi thứ hai để fread
.
Nếu ý tưởng này thực sự là rò rỉ bộ nhớ là giải thích chính xác (và không có bất kỳ lỗi nào ở nơi khác) thì bạn có thể khắc phục sự cố bằng cách tắt bộ đệm stdio cho tệp cụ thể này:
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));
}
}
Ngay cả khi chúng tôi đi với giả thuyết rằng đây thực sự là lỗi, và sự rò rỉ là có thật, nó cũng có giá trị ngưng tụ mã của bạn thành ví dụ nhỏ nhất có thể vẫn giải thích được vấn đề. Nếu làm điều đó cho thấy lỗi thực sự, bạn giành chiến thắng. Nếu không, bạn sẽ cần ví dụ tối thiểu để báo cáo lỗi trong quá trình triển khai.
điều gì xảy ra khi bạn thay đổi thành 'fread (magic, 1, 4, file);'? – Yahia
Bạn đã kiểm tra lỗi đọc (ví dụ: với 'ferror (tệp)')? – Beta
một điểm khác: kiểm tra kết quả của cuộc gọi 'fread'! – Yahia