我正在嘗試處理一些相當大的二進制文件(每個文件最多20GB)。要做到這一點,我想分塊讀取它們,處理並寫入新文件。二進制文件fread/fwrite和calloc/free內存泄漏?
爲了讀取文件,我使用:
fp = fopen(filename,"rb"); //open binary file to read
fseek(fp, start_of_chunk, SEEK_SET); //set cursor to current chunk
fread(data,size_of_chunk,1,fp); //read one chunk of data
fclose(fp);
我然後使用釋放calloc分配一些陣列和處理數據。 把它寫回,我用:
fout = fopen(file_out,"ab"); //open output binary file in append mode
fwrite(processed_data,size_of_processed_data,1,fout);
fclose(fout);
最後,我用免費的()在每個分配的變量(最大的一個是讀取數據塊(〜400 MB),最小的一個是關於1kB的)並開始閱讀下一個塊。
輸出工作正常,但進程保持進食記憶像沒有明天。一個800 MB的測試文件最多可以容忍6 GB的RAM,穩步增長。一次讀取整個文件幾乎與讀取塊相同的內存量。即使這些變量包含99%的數據,在循環之間使用free()也不會釋放已使用內存的5%。
由於我對C編程非常陌生,有什麼我可能會失蹤?我在另一個線程中看到,操作系統(我的情況是Windows 10 x64,Windows 7 x64上的相同問題)可能太慢而無法釋放內存。閱讀更大的塊在我的情況下沒有幫助。所有文件句柄在讀/寫後都會關閉,所有分配的數組在最後釋放。
編輯:我在循環內分配多次。我正在使用
free(data);
data = (uint16_t*)calloc(number_of_elements,sizeof(uint16_t));
每次調用讀取數據之前。處理大塊的某個部分,我正在使用
data_part = (uint16_t*)calloc(number_of_elements,sizeof(uint16_t));
memmove(data_part,pointer_to_part_of_chunk, size_of_data_part);
編輯2:我改變了一些東西,感謝評論。儘管如此,內存負載仍然穩步上升(比以前減慢)。下面的代碼再次:
//initiate variables
//allocate arrays
data = (uint16_t*)calloc(number_of_elements,sizeof(uint16_t));
array1 = (uint16_t*)calloc(number_of_elements1,sizeof(uint16_t));
array2 = (uint16_t*)calloc(number_of_elements2,sizeof(uint16_t)); //and so on
//some precalculations
//start of the loop
while (not_end_of_the_file){
fp = fopen(filename,"rb"); //open binary file to read
fseek(fp, start_of_chunk, SEEK_SET); //set cursor to current chunk
fread(data,size_of_chunk,1,fp); //read one chunk of data
fclose(fp);
//calculate stuff
start_of_chunk = start_of_chunk + increment;
for (i=0;i<I;i++){
memmove(array1,pointer_to_part_of_data, size_of_array1);
if (statement){
subfunction1(array1);
}
else{
subfunction2(array1);
}; //nothing more than some for loops, if statements and arithmetic operations
//NO further allocations here, all buffers will be reused
};
//write result
fout = fopen(file_out,"ab"); //open output binary file in append mode
fwrite(processed_data,size_of_processed_data,1,fout);
fclose(fout);
};
有一些分配的子功能發生,但內存應該釋放的子功能完成後,不應該嗎?
我們需要看到更多的代碼。聽起來好像你可能會在循環中重複分配內存,而不是隻重複使用一次。 – Barmar
很確定你在代碼中做錯了什麼,但你沒有向我們展示過。請發佈[MCVE](http://stackoverflow.com/help/mcve)。 – user3386109
@Barmar我確實多次分配。我會嘗試添加更多的代碼。 – Dominic