0

これが、リンクされたリストを破棄するための私のコードです。

void destroy(node *h){
    if (h->next!=NULL){
        destroy(h->next);
    }
    free(h);
    h=NULL;

}

問題は、印刷がまだたくさんの数字を出力することです:

11, 2, 15, 3, 9, //破壊前

28495936, 28495968, 28496064, 28496096, 0, //破棄後

残念ながらvoid destroy(node *h)、割り当ての理由により、パラメーターを変更できません。while ループ メソッドを使用してみましたが、それでも同じ結果が得られます。また、左にシフトして最後から削除しようとしましたが、最後のノードを削除できません。

前もって感謝します。

--編集--- リクエストに応じて、ここに印刷機能があります

void print(node* N){
        printf("%d, ", N->value);
    if (N->next)
        print_set(N->next);
    if (N == NULL)
        printf("Empty Set");
}
4

6 に答える 6

2

アルバートが提供する解決策がいくつかの規則のために不可能な場合、問題のソースの作成者であるあなたが持つ唯一の可能性は、リストのノードが割り当て解除されたため、メモリへの無効な参照が含まれていることと、あなたが書いたコードがつまり、未割り当て/割り当て解除されたメモリにアクセスすることによって未定義の動作が引き起こされるため、印刷関数に渡されない可能性があります。

このような安全でない可能性のあるコードを作成する場合は、作成者として、そのコードを慎重に使用し、プロジェクトを離れた後もコードを保守している仲間のプログラマーのために十分に文書化する責任があります。

于 2013-10-21T08:57:32.863 に答える
2

を設定する必要がありますh->next = NULL。また、 を呼び出した後はdestroy、ポインターが解放されるため、ポインターを使用しないようにしてください。したがって、常に の後destroy(n)に、 があることを確認してくださいn = NULL

より良い方法は、おそらく署名を に変更することvoid destroy(node **h)です。そのため、コードは次のようになります。

void destroy(node **h){
    if ((*h)->next!=NULL){
        destroy(&h->next);
    }
    free(*h);
    *h=NULL;
}

次に、後でポインターを使用していないことを確認します。

print関数では、このチェックを最初に追加する必要があります。

if(N == NULL) return;
于 2013-10-21T08:37:12.277 に答える
1

ここでの問題はh=null、関数が何もしないことです。ローカル パラメーターを変更しているため、関数の外部には影響しません。

したがって、唯一できることはメモリを解放することですが、アドレスは同じままにします。あなたのリストはまだ存在し、ランダムなメモリ位置を指しています(ランダムではありません:以前と同じですが、このメモリ位置の値はランダムです)

その後、リストを印刷すると (リストを破棄したはずなので、これは奇妙です...なぜもう一度印刷したいのでしょうか?)、ランダムな値をメモリに出力します。

プログラムがクラッシュする可能性があるため、これは問題です (割り当てられていないメモリにアクセスしています)。

残念ながら、この解決策では、関数の署名を変更する必要があります。

void destroy(node **h){
    if ((*h)->next!=NULL){
        destroy((*h)->next);
    }
    free(*h);
    *h=NULL;

}

できない場合は、次のように、ポインターを破棄した後にポインターを NULL に設定する必要があります。

void destroy(node *h){
    if (h->next!=NULL){
        destroy(h->next);
        h->next=NULL;
    }
    free(h);
}

そして呼び出し関数で:

destroy(myList);
myList=NULL;
于 2013-10-21T08:49:52.447 に答える
0

単一リンクリストで作業している場合は、このコードを試してください

void destroy(node *h){    
   node *n;    
   node *p; \\ variable to store previous term
   n=h;
   while(n->next!=NULL){
   p = n;
 }
  p->next=NULL;  
   free(n);

}

于 2013-10-21T08:50:01.887 に答える