2011-02-03 17 views
0

だから、少し問題があります。私はハッシュテーブルを構築しようとしていますが、 "互換性のないポインタ型からの復帰"というエラーが出ています。私はこれが何を意味するのか知っていますが、私のコードがなぜ機能していないのかわかりません。なぜ私のコードがうまくいかないのかの説明を探しています。配列をポインタとして認識しないのはなぜですか?構造体へのポインタの配列へのポインタを返す

私は、ハッシュテーブルの構造体へのポインタの配列を作成しています。 (私はまだ学んでいる>私は私のコードは、おそらく実際に吸うことを知っている<を!) は(外部チェーン)

struct hashTBL { 

    char *userID; 
    char *password; 
    struct hashTBL *next; 
}; 

typedef struct hashTBL Tbl; 
typedef struct hashTBL* TblPTR; 

TblPTR createHashTBL(int size) 
{ 
    char *userID; 
    char *password; 
    int i; 

    TblPTR hashArray[size]; 

    FILE* fpData; 
    char *fileName = "encrypted.txt"; 

    fpData = openReadFile(fileName); 

    TblPTR T = NULL; 

    while((fscanf(fpData, "%s", userID)) != EOF) 
    { 
     fscanf(fpData, "%s", password); 
     i = hash(userID, size); 



     if(hashArray[i] != NULL) 
     { 
      TblPTR H = hashArray[i]; 

      while(H != NULL) 
      { 
       T = H; 
       H = H->next; 
      } 
      H = newPTR(userID, password, T); 
     } 
     else 
     { 
      hashArray[i] = newPTR(userID, password, T); 
     } 

    } 
    closeFile(fpData); 
    return &hashArray; 
} 



TblPTR newPTR(char *userID, char *password, TblPTR T) 
{ 

    TblPTR H = (TblPTR)malloc(sizeof(Tbl)); 
    if(T != NULL) T->next = H; 
    H->userID = userID; 
    H->password = password; 
    H->next = NULL; 

    return H; 
} 
+0

コンパイラがどの行を表示していても、コード内のエラーを見つけるのは難しいですが、コードは有効です。どのラインで失敗するのですか? – Neil

+1

可能な限りコンパイル可能なコードサンプルを提供するか、エラーの発生場所を指定してください。私は 'TblPTR'が' Tbl * 'のtypedefだと仮定しますが、あなたは' Tbl'の定義を与えませんでした。 –

+0

return statment "互換性のないポインタ型からの復帰" "関数がローカル変数のアドレスを返します" – Bri

答えて

4

あなたは、少なくとも2つの問題があります。

まず、あなたのcreateHashTBL()機能はTblPTRオブジェクトを返すように定義されて、あなたはTblPTRオブジェクトの配列にポインタを返すしています。しようとしている戻り値の型に合わせて関数の型を変更するか、正しい型のオブジェクトを返す必要があります。

第2に、hashArraycreateHashTBL()関数内にスタック割り当てされています。つまり、ポインタを返すことはできません。あなたの関数が返ってきたら、それはなくなるでしょう。 malloc()で配列を割り当てるか、呼び出し元が事前に割り当てられた配列へのポインタを提供するようにしてください。

+0

'hashHeadArray'は' createHashTBL'内の* stack-allocated *です。 –

+0

AH! :)戻りポインタの型はどういうものでしょうか?あなたはどうやってそれをするのか正直には分かりません。 – Bri

+0

@larsmans:はい、もちろん修正済みです。 :-) – payne

2

がスタック上に作成され、返されません。これは、関数の最後に変数が破棄されるためです。

代わりにmalloc()を使用するか、static TblPTR hashArray[size];(推奨しません)を使用してください。

そして、これは間違っている:(TBLPTR *):

return &hashArray; 

あなたはあなたの配列へのポインタを返すされています。ちょうど

return hashArray; 
0

あなたのコンパイルエラーはまた、typedefの不足のような別の問題かもしれないことを示唆しています。エラーメッセージをコピーして貼り付けるだけでなく、貼り付けられたコードにエラーがどの行にあるのかを示すことができます。これは誰でも問題を理解するのに役立ちます。

ここにはいくつかのエラーがあります。

あなたはローカル変数へのポインタを返すことができません
TblPTR createHashTBL(int size) { 

... 
TblPTR hashArray[size]; 
.. 

return &hashArray; 
} 
  • - 関数は
  • createHashTableがTBLPTRを返すように宣言されて戻ったときにその変数がなくなっていますが、返却&hashArray。完全に異なる型を持っていれば、TblPTRの配列へのポインタです。

その関数はおそらく

TblPTR *createHashTBL(int size) { 

... 
TblPTR *hashArray = malloc(size * sizeof *hashArray); 
.. 

return hashArray; 
} 

()(解放するための要素と、あなたはそれで終わったhashArrayを忘れないでください)

0

する必要がありますあなたは2つの大きな問題があります。

  1. &hashArrayのタイプはTblPTR (*)[size]です(size -elemenへのポインタ)。 TblPTRのtアレイ)であり、TblPTRではない。それはあなたのタイプの不一致の警告がどこから来るかです。しかし、...

  2. hashArrayは、関数にローカルです。関数が終了すると、hashArrayはもはや有効ではなくなっているので、ポインタをガベージに戻すことになります。

VLAはここで使用するのに適したツールではありません。私は、次の変更を行うことをお勧め:あなたは後続のコードでfree()にいくつかの点で、配列を持っています

TblPTR *createHashArray(size)  // return a pointer to TblPTR 
{ 
    ... 
    TblPTR *hashArray = malloc(sizeof *hashArray * size); 
    if (hashArray) 
    { 
    // initialize hash array as you're currently doing 
    } 
    return hashArray; 
} 

注意を。

関連する問題