free()错误(用valgrind调试)?

时间:2009-09-01 07:46:38

标签: c memory-management memory-leaks free valgrind

我有这些结构:

typedef struct _Frag{
  struct _Frag *next;
  char *seq;
  int x1; 
  int length;  
}Frag;

typedef struct _Fragment{ 
  int type; 
  Frag *frag_list;   
}Fragment;

然后我创建了一个数组

Fragment *fragments=malloc(1,sizeof(Fragment)); // or more
fragments->frag_list=malloc(1,sizeof(Frag)); // or more
Frag *frag=malloc(10,sizeof(Frag));
frag->seq="test str\n";
...
frag->next=malloc(1,sizeof(Frag));
frag->next->seq="test str\n";

在程序结束时,我想释放内存,功能是:

static void free_frags(){
  int i;
  Fragment *fragment;
  Frag *current,*next;
  for(i=0;i<1;i++){
    fragment=&snp_frags[i];
    current=fragment->frag_list;
    next=current->next;

    while(next!=NULL){
      free(current->seq);
      //free(current->next);
      free(current);
      current=next;
      next=current->next;
    }
    free(current->seq);
    //free(current->next);
    free(current);
    //free(fragment->frag_list);
    free(&snp_frags[i]);
  }
  free(snp_frags);
}

如果我使用valgrind来调试它,valgrind说:

=============================================
==3810== Invalid read of size 4
==3810==    at 0x80490FD: free_snp (hap.c:16)
==3810==    by 0x80493AF: main (hap.c:73)
==3810==  Address 0x41b139c is 12 bytes inside a block of size 296 free'd
==3810==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==3810==    by 0x8049167: free_snp (hap.c:30)
==3810==    by 0x80493AF: main (hap.c:73)
==3810== 
==3810== Invalid free() / delete / delete[]
==3810==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==3810==    by 0x8049167: free_snp (hap.c:30)
==3810==    by 0x80493AF: main (hap.c:73)
==3810==  Address 0x41b1398 is 8 bytes inside a block of size 296 free'd
==3810==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==3810==    by 0x8049167: free_snp (hap.c:30)
==3810==    by 0x80493AF: main (hap.c:73)

请帮我解决这些错误,比如。

4 个答案:

答案 0 :(得分:7)

frag->seq="test str\n";

你没有malloc'内存块 - 字符串是在静态存储中分配的 - 后来你尝试free()那个内存块。您只能free()使用malloc()分配的块,否则您可能会遇到未定义的行为。

你可以只将指向静态分配字符串的指针放入Frag::seq字段,而不是free()字段,或者你可以为这些字符串malloc()内存并将字符串复制到malloc 'ed blocks。

答案 1 :(得分:1)

你似乎在说你正在释放这段记忆,这是该计划的最后一件事。

为什么要这么麻烦?为什么不退出?然后你的释放将是完美的,更快。 It is in fact the recommended technique.

我很确定没有评论者能够引用一个不会从终止程序释放内存资源的操作系统示例。没有这个关键的OS功能,^ C,kill,任务管理器,程序错误,程序崩溃......每次异常终止都会泄漏内存。

答案 2 :(得分:1)

  1. 您经常拨打molloc()而不是malloc()。检查你的元音。
  2. 您使用错误数量的参数调用malloc() - 只需要一个。
  3. 您无法分配字符串 - 执行指针分配,这不是您想要的。您必须使用strcpy()strncpy()memcpy(),根据您对整个*cpy()混乱的宗教观点,将一个字符串的内容复制到另一个字符串中。

答案 3 :(得分:0)

删除代码行“free(fragment)”。它会运作良好。