2009-09-01 29 views
0

私はこれらの構造体を持っている:そして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) 

そして、これらのエラーを修正するのを手伝ってください。文字列が静的ストレージに割り当てられている - -

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

+0

mallocの実装はどのようなものを使用していますか? POSIXは、mallocを "void * malloc(size_t size);"と定義しています。 あなたはまた私が今まで見たことがない 'モロック'を使用しているようです。それはタイプミスかもしれませんか? –

+0

@Kristof - POSIXは 'malloc()'を定義しません - ANSI/ISOはそうです。 –

答えて

0

コード行を削除してください(無料)。それはうまくいくでしょう。

7

あなたは、メモリブロックをエドないmalloc」は、後であなたはfree()そのメモリブロックにしてみてください。ブロックmalloc()で割り当てられるのはfree()ブロックのみです。そうしないと、定義されていない動作が発生する危険性があります。

あなたはどちらかだけを静的Frag::seqフィールドに文字列を割り当てられるためにポインタを置くと、決してfree()それらをか可能性があります可能性malloc()これらの文字列のためのメモリとmalloc「EDブロックに文字列をコピーします。

1

あなたはプログラムが行う最後のこととして、このメモリを解放していると言っているように見えました。

なぜ気になるのですか?なぜ終了しないのですか?その後、あなたの割り当て解除は完璧で速くなります。 It is in fact the recommended technique.

私はコメンターが終了したプログラムから空きメモリリソースをしないOSの例を引用することができなくなりますかなり確信しています。この重要なOS機能がなければ、^ C、kill、タスクマネージャー、プログラムのバグ、プログラムのクラッシュ...異常終了するたびにメモリがリークします。

+0

私はダウンボートしませんでしたが、終了する前にあなたの記憶を解放することをお勧めします。 OSはあなたのためにそれを掃除する良い仕事をする必要はありません。 –

+0

ひどいアドバイス。とにかくOSがメモリを取り戻すのはあなたのプラットフォームの場合かもしれませんが、このプラクティスはそれ以上拡張することはできません。リソースはどうですか?メモリだけでなく、オープンファイル、またはオープンネットワーク接続。今では、他のプログラムでは使用できないリソースを永久に奪っているので、「放置する」ことはできません。正確さと一貫性を追求する。 – GManNickG

+0

その後、彼または他の誰かがこのコードを本番システムにコピーペーストし、素敵なメモリリークを取得します。それはしません。 – sharptooth

1
  1. malloc()ではなく、molloc()と頻繁に電話しています。あなたの母音をチェックしてください。
  2. malloc()には引数の数が間違っています.1つしかかかりません。
  3. あなたは、文字列を代入することはできません - あなたが望むものではありませんポインタ割り当てを、実行しています。あなたは別のものに1つの文字列の内容をコピーするために、全体*cpy()混乱にあなたの宗教的な視点に応じて、strcpy()またはstrncpy()またはmemcpy()を使用する必要があります。