结构上的 free() 无效

Invalid free() on structure

我正在从文件中提取信息并将它们插入结构中。但是,我很难在 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)

对于此处分配的列表中的第一个元素

CodeList* helpread(const char *filename){
  char curr[256];
  FILE *f;
  CodeList *code = malloc(sizeof(CodeList));

...代码未初始化成员 content,因此它指向任何地方。代码应将其初始化为 NULL.


此外,代码从不对 malloc()fopen() 的结果进行任何错误检查。


此外^2代码不以安全的方式处理空文件或读取错误的情况。

read_commands 中,malloc 缓冲区未被 return 编辑。正在 returned 结构的副本(按值)。

Commands *ans = malloc(sizeof(Commands));
if(ans != NULL){
    ....
    return *ans;
}

您还没有说明 read_commands 是如何被调用的。但是无论怎么调用,ans指向的buffer都丢失了,无法释放。因此,我假设您以某种方式释放了您认为是动态分配的 Commands 结构,而实际上并非如此。

read_commands 函数应该声明为 return Commands * 而不是 Commands 然后它应该 return ans 而不是 *ans.

为了更加确定,请说明如何调用 read_commands