2017-12-01 6 views
2

次のコードの一部は、K & R.から単純なハッシュルックアップアルゴリズムの実装テーブルで秒間 ルックアップ検索され、それが発見された場所、またはNULLを指すポインタを返しますそれがなかった場合:K&Rハッシュ関数

struct hashElement *lookup(char *name){ 
    struct hashElement *currentStruct; 
    int cmp; 
    for (currentStruct = hashTable[calcIndex(name)]; currentStruct; currentStruct = currentStruct->p) 
    if (cmp = strcmp(name, currentStruct->name) == 0) 
     return currentStruct; 
    return NULL;} 

は名前がインストールされているかどうかを判断するために検索を使用してインストールすることは、すでに存在している:

struct nlist *install(char *name, char *defn) 
{ 
    struct nlist *np; 
    unsigned hashval; 
    if ((np = lookup(name)) == NULL){ 
    np = (struct nlist *) malloc(sizeof(*np)); 
    ...} 
...} 

ルックアップがNULLを返す場合は、という名前のがハッシュテーブルにインストールされていることを意味します。このタイプはnlistになる新しい要素のメモリを割り当てる必要があります。

しかし、このnp = (struct nlist *) malloc(sizeof(*np));に基づいて、ルックアップがNULLを返す場合、npはNULLのためにメモリを割り当てます。 * npの代わりに常にnlistのメモリサイズを割り当てるべきではありませんか?

+0

「sizeof(* np)」を印刷するとどうなりますか?たぶん、あなたが実際にどのスペースを割り当てているのか、いくつか考えているでしょう。 – babon

+0

ようこそスタックオーバーフロー! [malloc()とfamilyの戻り値をC ..にキャストしない理由についてのこのディスカッションを参照してください](https://stackoverflow.com/q/605845/2173917) –

答えて

1

*ルックアップがNULLを返した場合、npはNULL用にメモリを割り当てます。

いいえ、それは当てはまりません。

np = (struct nlist *) malloc(sizeof(*np)); 

the cast in not needed

まず第一に、。すなわち

np = malloc(sizeof(*np)); 

np = malloc(sizeof(struct nlist)); 
*np

のタイプはstruct nlistであるよう

と同じであることを特徴とします。 sizeofオペレータはVLAでない限りオペランドを評価しません。 C11を引用する

、章§6.5.3.4

sizeofオペレータは 発現またはタイプの括弧名前であってもよい、そのオペランドのサイズ(バイト数)が得られます。サイズは、オペランドの のタイプから決定されます。結果は整数です。オペランドの型が可変長配列 型の場合、オペランドは評価されます。それ以外の場合、オペランドは評価されず、結果は 整数定数になります。