ошибки free () (отладка с помощью valgrind)? - PullRequest
0 голосов
/ 01 сентября 2009

У меня есть эти структуры:

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 ]

7 голосов
/ 01 сентября 2009

В

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

вы не malloc 'редактировали блок памяти - строка выделяется в статическом хранилище - и позже вы пытаетесь free() этот блок памяти. Вы можете использовать только free() блоков с malloc(), в противном случае вы рискуете столкнуться с неопределенным поведением.

Вы можете либо поместить указатели на статически размещенные строки в поля Frag::seq и никогда не free() их, либо malloc() память для этих строк и скопировать строки в malloc 'ed блоки.

1 голос
/ 01 сентября 2009
  1. Вы часто звоните molloc() вместо malloc(). Проверьте свои гласные.
  2. Вы звоните malloc() с неправильным количеством аргументов - он принимает только один.
  3. Вы не можете назначать строки - это выполняет указатель назначение, что не то, что вы хотите. Вы должны использовать strcpy() или strncpy() или memcpy(), в зависимости от вашей религиозной точки зрения на весь беспорядок *cpy(), чтобы скопировать содержимое одной строки в другую.
1 голос
/ 01 сентября 2009

Вы, кажется, говорили, что освобождаете эту память как последнее, что делает программа.

Зачем беспокоиться? Почему бы просто не выйти? Тогда ваше освобождение будет совершенным и быстрее. На самом деле это рекомендуемая техника.

Я почти уверен, что ни один комментатор не сможет привести пример ОС, которая не освобождает ресурсы памяти от программ, которые завершаются. Без этой критически важной функции ОС ^ C, kill, диспетчер задач, программные ошибки, программные сбои ... каждое аварийное завершение приведет к утечке памяти

0 голосов
/ 03 сентября 2009

удалить строку кода "свободный (фрагмент)". Это будет хорошо работать.

...