web-dev-qa-db-ja.com

サイズ8の無効な読み取り-Valgrind + C

Valgrindは、次のコードでエラー_Invalid read of size 8_を報告します。

次のように宣言された配列があります。

_struct symbol *st[PARSER_HASH_SIZE];
_

プログラムが初期化されると、この配列内のすべての要素は0として初期化されます。

_memset(&st[0], 0, sizeof(st));
_

私のプログラムは_struct symbol_のインスタンスを作成し、ハッシュ値に応じて上記の配列に挿入します。したがって、この配列内の要素の一部はNULLになり、その他は有効な値になります。

次のコードは、割り当てられたアイテムを削除しようとし、_sym = st[i]; sym != NULL; sym = sym->next_の行でvalgrindが文句を言います。

_struct symbol *sym = NULL;

/* cleaning the symbol table entries */
for(i = 0; i < PARSER_HASH_SIZE; i++) {
    for(sym = st[i]; sym != NULL; sym = sym->next) { /* <-- Valgrind complains here */
        free(sym);
    }
}
_

このエラーの理由を理解しようとしています。

どんな助けも素晴らしいでしょう!

22
Navaneeth K N

問題は、symを解放してから、(現在解放されている)データから値にアクセスしようとすることです:sym->next

おそらく、内側のループに次のようなものが必要です。

struct symbol *next_sym = NULL;

for(sym = st[i]; sym != NULL; ) {
    next_sym = sym->next;
    free(sym);
    sym = next_sym;
}
42
ZoogieZork

配列が構造体または構造体へのポインタを含むことを意図しているかどうかも明確ではありません

struct symbol *st[PARSER_HASH_SIZE];

構造体へのポインタの配列を言います。しかし、あなたは言う

「私のプログラムが初期化されると、この配列内のすべての要素は0として初期化されます。」

memset(&st[0], 0, sizeof(st));

これは、エントリを構造体のように扱っています

配列をクリアするには

for (int i = 0; i < PARSER_HASH_SIZE; i++)
{
    st[i] = 0;
}
3
pm100