[英]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.