1

Cでリンクリストを解放したいのですが、すべて正常に機能していますが、Valgrindが教えてくれます

Conditional jump or move depends on uninitialised value(s)
    at 0x401400: mtf_destroy

コードは次のとおりです。

list_elt *head;

void mtf_init() {
    list_elt *current;
    head = malloc(sizeof(list_elt));
    current = head;
    for (int i = 0; i < LIST_SIZE-1; i++) {
        current->value = (BYTE) i;
        current->next = malloc(sizeof(list_elt));
        current = current->next;
    }
    current->value = LIST_SIZE-1;
}

void mtf_destroy(list_elt *elt) {
    if (elt->next != NULL)
        mtf_destroy(elt->next);
    free(elt);
}

どうすればこれを解決できますか?ありがとう!

4

1 に答える 1

4

elt->nextValgrindは、式として使用されるインスタンスif()が初期化されていないことを通知したいので、によって行われる決定if()はランダムです。

あなたは変更したいかもしれません:

head = malloc(sizeof(list_elt));
...
  current->next = malloc(sizeof(list_elt));

することが:

head = calloc(1, sizeof(list_elt));

..."
  current->next = calloc(1, sizeof(list_elt));

移植可能なアプローチは、以下を使用してすべてのポインタを明示的に初期化することNULLです。

head = calloc(1. sizeof(list_elt));
head->next = NULL;
...
  current->next = calloc(1, sizeof(list_elt));
  current->next->next = NULL;

(これの背景は、すべてのシステムでポインターが必ずしも文字のシーケンス(バイト)NULLで表されるわけではないということです)。NUL

nextとにかく、あなたがの定義を投稿しなかったので、あなたが正しいものを割り当てるかどうかはわかりませんlist_elt


アップデート:

への再帰呼び出しを再利用するmtf_destroy()

再帰は見た目がかっこよく、実際に多くの問題に対する洗練された解決策ですが、再帰を使用すると、システムリソース(メモリ)を消費するため、たとえば、非常に深くなる場合など、エラーが発生しやすくなります。

したがって、リストが非常に長い場合は、リストを破棄するとコードが破損する可能性があります。

私のアドバイス:少なくとも、事前に実行される再帰レベルを予測できない場合は、再帰なしで実行してみてください。

于 2012-11-24T10:46:04.393 に答える