我从文件中提取信息并将它们插入到结构中。但是,我很难在C中释放这个结构。结构如下:
typedef struct codelist{
char *content;
struct codelist *next;
}CodeList;
typedef struct comm{
CodeList *compile;
CodeList *test;
} Commands;
这里我在文件info和malloc中读取CodeList和Commands结构
/*opens compile_cmds and test_cmds and puts their contents into a Command.
Exits with 0 if error is found*/
Commands read_commands(const char *compile_cmds, const char *test_cmds){
int status = 1;
FILE *f1, *f2;
if(compile_cmds == NULL || test_cmds == NULL)
status = 0;
f1 = fopen(test_cmds, "r");
f2 = fopen(compile_cmds, "r");
/*checks if compile_cmds and test_cmds are openable files*/
if(f1 == NULL || f2 == NULL){
status = 0;
}
fclose(f1);
fclose(f2);
/*create dummy headers for compile and test lists*/
if(status != 0){
Commands *ans = malloc(sizeof(Commands));
if(ans != NULL){
ans->compile = helpread(compile_cmds);
ans->test = helpread(test_cmds);
return *ans;
}
}
exit(0);
}
/*takes info out of filename and puts it into a linked list of content
return content*/
CodeList* helpread(const char *filename){
char curr[256];
FILE *f;
f = fopen(filename, "r");
CodeList *code = malloc(sizeof(CodeList));
if(code !=NULL && f != NULL){
code->content = NULL;
while(fgets(curr, 256, f)){
CodeList *new = malloc(sizeof(CodeList));
if(new == NULL)
break;
new->content = malloc(sizeof(char)*(strlen(curr)+1));
if(new->content == NULL)
break;
strcpy(new->content, curr);
new->next = NULL;
code->next = new;
code = new;
}
}
fclose(f);
return code;
}
在我完成它们之后,我清除这些结构,以便使用的内存应为0。 读命令运行良好,清除命令不是什么。虽然我能够释放二级结构,但释放实际的Commands结构会在valgrind中给出一个无效的free()。有人可以帮我解决这个问题吗?
/*clears CodeList
returns number of elements that were in CodeList*/
int helpclear(CodeList *code){
int ans = 0;
CodeList *prev;
while(code !=NULL){
prev = code;
code = code->next;
free(prev->content);
free(prev);
ans++;
}
return ans;
}
void clear_commands(Commands *commands){
printf("enter clear_commands\n");
if(commands !=NULL){
helpclear(commands->test);
helpclear(commands->compile);
free(commands);
}
printf("done freeing test and compile\n");
printf("end clear_commands\n");
}
此外,这是valgrind的结果:
==17133== Invalid free() / delete / delete[] / realloc()
==17133== at 0x4C27430: free (vg_replace_malloc.c:446)
==17133== by 0x400E50: ??? (in /afs/glue.umd.edu/class/fall2015/cmsc/216/0101/student-cmsc216-0403/chan2017/project6/public03.x)
==17133== by 0x400B8F: ??? (in /afs/glue.umd.edu/class/fall2015/cmsc/216/0101/student-cmsc216-0403/chan2017/project6/public03.x)
==17133== by 0x4E4DD5C: (below main) (in /lib64/libc-2.12.so)
==17133== Address 0x7ff000570 is on thread 1's stack
==17133==
Your code has a memory leak; memory still in use is 304 bytes.
==17133==
==17133== HEAP SUMMARY:
==17133== in use at exit: 257 bytes in 13 blocks
==17133== total heap usage: 20 allocs, 8 frees, 2,561 bytes allocated
==17133==
==17133== LEAK SUMMARY:
==17133== definitely lost: 138 bytes in 5 blocks
==17133== indirectly lost: 119 bytes in 8 blocks
==17133== possibly lost: 0 bytes in 0 blocks
==17133== still reachable: 0 bytes in 0 blocks
==17133== suppressed: 0 bytes in 0 blocks
==17133== Rerun with --leak-check=full to see details of leaked memory
==17133==
==17133== For counts of detected and suppressed errors, rerun with: -v
==17133== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
答案 0 :(得分:4)
在read_commands
中,未返回malloc
缓冲区。正在返回结构的副本(按值)。
Commands *ans = malloc(sizeof(Commands));
if(ans != NULL){
....
return *ans;
}
您尚未显示如何调用read_commands
。但无论如何调用它,ans
指向的缓冲区都会丢失并且无法释放。所以我假设你在某种程度上解放了你认为动态分配的Commands
结构,而实际上并非如此。
应声明read_commands
函数返回Commands *
而不是Commands
,然后它应返回ans
而不是*ans
。
为了更加确定,请说明如何调用read_commands
。
答案 1 :(得分:0)
对于此处分配的列表中的第一个元素
CodeList* helpread(const char *filename){
char curr[256];
FILE *f;
CodeList *code = malloc(sizeof(CodeList));
...代码错过初始化成员content
,所以它指向无处。代码应将其初始化为NULL
。
此外,代码永远不会对malloc()
和fopen()
的结果进行任何错误检查。
此外,代码不能以安全的方式处理空文件或读错误的情况。