1. ホーム
  2. c

[解決済み】ヒープ割り当てで初期化されていない値が作成された

2022-01-31 08:09:35

質問

ハッシュテーブルを使って単語の辞書を実装しようとしているので、それをグローバルにする必要があり、ヘッダーファイルの1つでそれを宣言しています。

extern node** dictionary;

ノードがある場所

typedef struct node
{
    char* word;
    struct node* next;
} node;

そして、関数が定義されている別のファイルに、辞書の宣言があるヘッダをインクルードし、さらに、一番上に

node** dictionary;

そして、実際に辞書を読み込む関数で、まずハッシュテーブルを構成するリンクリストのメモリを確保します。

bool load(const char* dict_file)
{
    dictionary = malloc(sizeof(node*) * LISTS);

    FILE* dict = fopen(dict_file, "r");

    if(dict == NULL)
        return false;

    char buffer[MAX_LEN + 2];

    size_dict = 0;

    while(fgets(buffer, MAX_LEN + 2, dict) != NULL)
    {
        node* new_node = malloc(sizeof(node));

        int len = strlen(buffer);

        new_node->word = malloc(sizeof(char) * (len));

        //avoid \n
        for(int i = 0; i < len - 1; i++)
            new_node->word[i] = buffer[i];

        new_node->word[len - 1] = '\0';

        new_node->next = NULL;

        int index = hash(buffer);

        new_node->next = dictionary[index];

        dictionary[index] = new_node;

        size_dict++;
    }

    if (ferror(dict))
    {
        fclose(dict);
        return false;
    }

    fclose(dict);
    return true;
}

そこで、プログラムは正常に動作し、文字列とノードに割り当てられたメモリをすべて解放して、valgrind(メモリリークを検出するデバッガ)を実行すると、メモリリークの可能性はないと言いますが、エラーが発生すると言います。 未使用の値がヒープ・アロケーションによって作成されました。 のメモリーを確保している行にリダイレクトされます。 dictionary というのは、上に書いたload関数の最初の行と全く同じです。
何が間違っているのでしょうか?私は、私が使用する方法だと思います dictionary どなたか、このエラーを避けるために、グローバルに保つ他の方法を教えてください。

どのように解決するのですか?

更新されたコードでは、初期化されていないポインタが使用されています。

dictionary = malloc(sizeof(node*) * LISTS);

// .... code that does not change dictionary[i] for any i

new_node->next = dictionary[index];   // use uninitialized pointer

既に書かれているように、これは、すべてのポインタをあらかじめ NULL このループに入る前に

dictionary = malloc(sizeof(node*) * LISTS);
if ( !dictionary ) {
    return false;
}

for (size_t i = 0; i < LISTS; ++i) {
    dictionary[i] = NULL;
}