3

関数を呼び出すと、関数b_destroyの最後に到達する前にプログラムがクラッシュします。関数は次のようになります。

void b_destroy(Buffer * const pBD){
#ifdef DEBUG
printf("IN DESTROY\n");
printf("BUFFER ADDRESS %d\n",pBD);
printf("HEAD ADDRESS %d\n",pBD->ca_head);
#endif
if(pBD != NULL || pBD->ca_head != NULL){
    if (pBD->ca_head != NULL)
        free(pBD->ca_head);
    if (pBD != NULL)
        free(pBD);
}
#ifdef DEBUG
    printf("EXITING DESTROY\n");
#endif
}

NULLメモリの場所を印刷できるので、ポインターがそうではないことはわかっています。クラッシュする理由はありますか?

4

3 に答える 3

2

ここでロジックを慎重に検討してください。

if(pBD != NULL || pBD->ca_head != NULL)

pBD が 0 の場合、ロジックは次のようになります。

if(0 || 0->ca_head != NULL) { // that 0-> will seg fault

}

多分あなたは次のようなものが欲しい:

if (pBD && pBD->ca_head)
    free(pBD->ca_head);
if (pBD)
    free(pBD);
于 2013-09-24T15:27:38.340 に答える
2

ポインターを解放するときは、常にポインターをすぐに NULL に設定する必要があります。そうしないと、プログラムの他の場所でクラッシュする可能性があります。それはあなたのプログラムに当てはまるかもしれません。また、%d (符号付き整数の場合) ではなく、常に %x (メモリ アドレスの場合) 形式指定子を使用してアドレスを出力します。

問題を見つけるには、プログラム全体を調べる必要があります。問題を解決する可能性のあるすべての場所で解放した後、ポインターを NULL に設定してみてください。

于 2013-09-24T15:15:31.073 に答える
1

アドレスが null でないことは重要ではありませんが、そこにあるデータがまだ解放されていないことは重要です。Free は指定されたポインターを null のあとがきに設定しないため、同じメモリが既に解放されているかどうかを確認するには、他の場所を検索する必要があります。

于 2013-09-24T15:07:36.223 に答える