[英]How can I prevent the current memory leaks in my C program?
我有一個程序,我將文本文件中的數據加載到結構數組中。 我的結構如下所示:
typedef struct A {
int id;
char* name;
char* desc;
} A;
我開始從我的主 function 加載文件:
int main(void) {
A* a;
int* length = 0;
arr = betolt("name.txt", &length);
...
free(arr);
return 0;
}
然后 - 在不同的 header 文件中 - 真正的邏輯是這樣發生的:
A* load(char* file_name, int* length) {
FILE* fp = fopen(file_name, "r");
if (fp == NULL) return NULL;
size_t ar_length = 500;
size_t line_counter = 0;
char** lines = malloc(ar_length);
char line[256];
while (fgets(line, sizeof(line), fp)) {
lines[line_counter] = malloc(256);
strcpy(lines[line_counter], line);
line_counter++;
if(line_counter > sizeof(lines)){
ar_length *= 2;
lines = realloc(lines, ar_length);
}
}
*length = line_counter;
fclose(fp);
return process(lines, line_counter);
}
A* process(char** lines, int length) {
A* arr = (A*) malloc(length * sizeof(A));
for (int i = 0; i < length; ++i) {
char* line = lines[i];
char* ptr = strtok(line, ";");
A a;
a.id = i;
int j = 0;
while (ptr != NULL) {
if (j == 0) {
a.name = ptr;
} else if (j == 1) {
a.desc = ptr;
}
j++;
ptr = strtok(NULL, ";");
}
arr[i] = a;
}
return arr;
}
我的程序工作得很好,但是,由於malloc(256)
的原因,每條加載的行都有 memory 泄漏,並且在使用realloc(lines, ar_length);
我很不確定為什么會出現這些泄漏,因為它不應該在 function 運行后“自動釋放” memory 嗎? 如何修復這些 memory 泄漏? 提前致謝。
您的代碼存在幾個一般性問題。
int* x = malloc(200*sizeof(int));
//whatever
int* bigger_x = realloc(x, 400*sizeof(int));
if(bigger_x) x = bigger_x;
else handle_error("realloc");
至於更具體到您的問題和問題的要點:
我很不確定為什么會出現這些泄漏,因為它不應該在 function 運行后“自動釋放” memory 嗎? 如何修復這些 memory 泄漏?
不,這不對。 一般來說,一旦你完成使用它,你應該清理使用過的 memory。 什么時候? 好問題;)請注意,您正在使用指向動態分配數組的指針,例如: a.desc = ptr;
. 一個簡單的解決方案是復制每個字符串,即a.desc = strdup a.desc = strdup(ptr);
, 然后process()
返回后的空閑lines
。 請注意,您的strdup
實際上確實分配了,因此您需要在使用完它們后釋放它分配的資源。
-fsanitize=address
進行編譯,這將為您提供大量有關泄漏內容和位置的信息。 clang 和 gcc 的現代版本支持它。 Valgrind 也是 go 的一種方式,但恕我直言,它不太方便。加分項:C 沒有 RAII,但無論如何您都可以使用一些基本的“范圍保護”技術。 考慮以下代碼:
char* buffer = malloc(300);
if(buffer) {
//do whatever
}
free(buffer);
如果你最后忘記了free()
,你就會有一個 memleak。 您可以做的是以稍微有創意的方式使用 for 循環來引入“范圍保護”:
for(char* buffer = malloc(300); buffer; free(buffer), buffer=NULL)
{
//do stuff
}
類似的技術也應該適用於FILE*
和其他資源,或者可以使用宏進行概括,由您決定是否喜歡。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.