0

私の質問は簡単だと思います。はい、スタックオーバーフローに関するリンクリスト/セグメンテーションフォールト関連の質問がいくつかあることは承知していますが、それらは初期化されていないポインターに関係していると思いますが、私の問題は文字列に関連していると思います.

ノード構造が 2 つの変数で構成されるリンク リストがあります。nextノードへのリンクと (!) astringです。

私の質問:文字列を ing しmallocてセグメンテーション違反を引き起こすことなく、ノードのメモリを解放するにはどうすればよいですか?free()

free()とに関連する他の質問を閲覧しているうちstringsに、それらには必要ないという印象を受けましfree()た。しかし、内部にネストされた文字列structを持つ a を解放するにはどうすればよいでしょうか。string

私が実装しているリンクリスト関数はdestroyList()、関数に渡されたノードの割り当てられたすべてのメモリを後続のすべてのノードとともに解放する以外は機能しているようです。

実装は次のとおりです。

void destroyList(struct listNode *pNode){
    if(pNode->next != null){
        destroyList(pNode->next);
    }
    free(pNode);
}

listNode構造は次のとおりです。

struct listNode{
    char addr[MAX_ADDR_LENGTH];
    struct listNode *next;
};
4

4 に答える 4

1

経験則では、malloc() を使用した場合は free() を使用します。ノードを free() すると、文字列のメモリを含む構造全体に割り当てられたメモリの割り当てが解除されるため、文字列を free() する必要はありません。そして、gdb または valgrind を使用して、正確に障害が発生した場所をデバッグしないのはなぜですか? gdb では、where や print stacktrace などのオプションを使用して、segfault が発生している場所を正確に特定できます。今gdbを学ぶのは良い投資です。コードのこの部分は私には問題ないようです。

于 2013-10-02T16:36:01.970 に答える
0

malloc(または類似のもの)を持つものだけが必要になりfreeます。

たとえば、構造体が次のような場合:

struct listNode{
    char *addr;
    struct listNode *next;
};

次に、次のように割り当てます。

struct ListNode Node = malloc(sizeof(struct listNode));
Node.addr = malloc(size of the string);

また、ノード自体を解放する前に文字列を解放する必要があります。固定長の構造体の一部としての文字列であるため、解放する文字列はありません。

しかし、あなたの問題は別のものでなければなりません。再帰を避けるようにしてください(つまり、あなたの例では再帰を使用しています - 大きなリストではスタックオーバーフローが発生します)、ポインタを解放するときにポインタを無効にし、ポインタを使用する前に(nullでないことを)確認してください。

于 2013-10-02T15:14:59.937 に答える
0

おそらくスタックをオーバーランしました。

これを試して:

void destroyList(struct listNode *pNode){
    while (pNode) {
        struct listNode *x = pNode;
        pNode = pNode->next;
        free(x);
    }
}

もちろん、不正な pNode を渡した可能性もありますが、その場合は修正されません。

または、他の場所でヒープを破損しています。

于 2013-10-02T15:16:49.460 に答える