2017-05-28 5 views
1

解放された値を読んでいません。私は自由なを使用する場合 私の問題がある()ポインタ値はNULLなりません。印刷機能は、私が探索木で働いている、と木が、それがnullだ場合、私がチェックし終わったかどうかを確認するために、正しく

私も解放するためにポインタを使用してみました、その後、NULLに設定するが、それはうまくいきませんでしたしました。この場合

私は探索木上で最大の番号を削除したいが、私の印刷機能ではなく、解放された値と印刷物0を認識しません。

typedef struct nodo { 
    int val; 
    struct nodo *l, *r; 
} *ABin; 

void print (ABin a) { 
    if (a != NULL) { 
     print (a -> l); 
     printf(" %d ",a -> val); 
     print (a -> r); 
    } 
} 

ABin remBiggerA (ABin *a) { 
    ABin b = (*a), aux = b; 
    int i = 0; 
    if (b == NULL) i = 1; 
    while (i == 0) { 
     if (b -> r == NULL) { 
      free (b); 
      i = 1; 
     } 
     else b = b -> r; 
    } 
    (*a) = aux; 
    return aux; 
} 
+2

ポインタを 'typedef'するのは悪い考えです。 –

+0

私はすでに提供されている情報を与えられた最良の答えを与えましたが、解放されたポインタをヌルに設定してもヌルチェックが登録されていなければ、まったく異なる(ほとんど論理ベースの)問題が発生しています。最小限の検証可能な例を投稿することは可能ですか? –

答えて

4

ポインタにfree()を呼び出した後、ポインタをNULLに設定しないと無効になります。これは、そのポインタアドレスへのさらなるアクセスが未定義の動作をもたらすことを意味する。すでに解放されているメモリから情報にアクセスしたり印刷したりすることはできません。しかし、ポインタを解放してすぐにそれをnullに設定することができます。これは完全に有効なことです。これを既に実行しても問題が残っている場合は、問題が他の場所にあると思われます。

2

これは正常な動作です。 free()関数のドキュメントはThe GNU C Libraryにあります。ブロックの解放

は、ブロックの内容を変更します。ブロック内の任意のデータ(ブロックのチェーン内の次のブロックへのポインタなど)を解放した後に、そのブロック内で見つけることは期待しないでください。

ヒコで述べたように、free()を呼び出した後NULLにポインタを割り当てることをお勧めします。

ので、

free (b); 
b = NULL; 

はあなたの問題を解決します。


編集:コメントで@Sebによって推奨されているように、またThe POSIX manual for free()をご確認ください。

+2

GNUマニュアルではなく、POSIX(opengroup)マニュアルを参照することをお勧めします。前者は、より正確で標準に準拠している傾向があります。 [POSIXの 'free'のマニュアルはここにあります(http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html)。それにもかかわらず、OPをマニュアルにすることは素晴らしい考えです! – Sebivor

+0

おそらく、ページが将来移動される場合にglibcのドキュメントのように追加したマニュアルリンクから「ポインタの使用」テキストを追加する必要があります。 –

関連する問題