[英]How can I prevent the current memory leaks in my C program?
I have a program where I load data from a text file into an array of structs.我有一个程序,我将文本文件中的数据加载到结构数组中。 My struct looks like this:
我的结构如下所示:
typedef struct A {
int id;
char* name;
char* desc;
} A;
I start loading the file from my main function:我开始从我的主 function 加载文件:
int main(void) {
A* a;
int* length = 0;
arr = betolt("name.txt", &length);
...
free(arr);
return 0;
}
Then - in a different header file - the real logic happens like this:然后 - 在不同的 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;
}
My program works just fine, however, I got memory leaks for each loaded line because of the malloc(256)
, and I also got memory leak after using realloc(lines, ar_length);
我的程序工作得很好,但是,由于
malloc(256)
的原因,每条加载的行都有 memory 泄漏,并且在使用realloc(lines, ar_length);
I'm quite unsure why I get these leaks because isn't it supposed to "automatically free" the memory after a function runs?我很不确定为什么会出现这些泄漏,因为它不应该在 function 运行后“自动释放” memory 吗? How can I fix these memory leaks?
如何修复这些 memory 泄漏? Thanks in advance.
提前致谢。
There are several general problems with your code.您的代码存在几个一般性问题。
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");
As for points more specific to your question and problems:至于更具体到您的问题和问题的要点:
I'm quite unsure why I get these leaks because isn't it supposed to "automatically free" the memory after a function runs?
我很不确定为什么会出现这些泄漏,因为它不应该在 function 运行后“自动释放” memory 吗? How can I fix these memory leaks?
如何修复这些 memory 泄漏?
No, it's not.不,这不对。 Generally you should clean up the used memory once you're done with using it.
一般来说,一旦你完成使用它,你应该清理使用过的 memory。 When?
什么时候? Good question;) Note, that you're using pointers to the dynamically allocated array, eg here:
a.desc = ptr;
好问题;)请注意,您正在使用指向动态分配数组的指针,例如:
a.desc = ptr;
. . A trivial solution would be to str ing dup licate each of those string, ie
a.desc = strdup(ptr);
一个简单的解决方案是复制每个字符串,即a.desc = strdup
a.desc = strdup(ptr);
, then free lines
after process()
returns. , 然后
process()
返回后的空闲lines
。 Note, that you strdup
actually does allocate, so you need to release the resources allocated by it once you're done with them.请注意,您的
strdup
实际上确实分配了,因此您需要在使用完它们后释放它分配的资源。
-fsanitize=address
, that will give you plenty of info of what and where is leaking.-fsanitize=address
进行编译,这将为您提供大量有关泄漏内容和位置的信息。 Conteporary version of clang and gcc support it. Bonus point: C does not have RAII, but you can utilize some basic "scope guard" techniques anyway.加分项:C 没有 RAII,但无论如何您都可以使用一些基本的“范围保护”技术。 Consider the following code:
考虑以下代码:
char* buffer = malloc(300);
if(buffer) {
//do whatever
}
free(buffer);
Should you forget about free()
at the end, you'll have a memleak.如果你最后忘记了
free()
,你就会有一个 memleak。 What you can do instead is use for loop in slightly creative way to introduce a "scope guard":您可以做的是以稍微有创意的方式使用 for 循环来引入“范围保护”:
for(char* buffer = malloc(300); buffer; free(buffer), buffer=NULL)
{
//do stuff
}
Similar technique should also works for FILE*
and other resources or can be generalized using macros, it's for you to decide whether you like it or not.类似的技术也应该适用于
FILE*
和其他资源,或者可以使用宏进行概括,由您决定是否喜欢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.