3

みなさんこんにちは!

ゲーム Clever Frog のコードをテストしようとしたときに、次のエラーが発生しました: エラー: 不完全な型へのポインターを逆参照しています。

「完全なコード」は、pastebin.com にあります -こちら(有効期限はありません)。しかし、以下の説明で誰でも理解できると思います。注:割り当てられたメモリなどを消去する機能はまだ実装していません。

1.c ファイルで定義された構造体があります。

#include "1.h"
...
struct test {
   int a;
   };
...

私はそれを使用するtypedefを持っている1.hを持っています:

...
typedef struct test testT;
...

次に、2.cにあるtestTに応じてパラメーターを持つ関数があります。

...
void funcTest(testT **t, int *size, ..){
   /* another function that creates mem.space/alocate memory based enter code here`on the need of size above */
   createMem(t,*size); /* void createMem(testT **t, int size); */

   t[0]->a = 0; /*ERROR HERE*/
   /* ... more code ... */
}
...

2.h ファイルは次のようになります。

...
void funcTest(testT **t, int *size, ..);
...

メインプログラムで、以下のようにtestT *varを渡します。

...
testT *varTest; int size;

funcTest(&varTest, &size);
...

奇妙なことは、1.h ファイルで構造体テストを使用するとコードがコンパイルされることです (構造体テストを 1.c から削除する - これは間違っています)。しかし、コンパイルされたプログラムを実行すると、エラーが発生する正確な場所はt[0]->aの場所です。

私はすでに「すべて」を試しましたが、何も機能しませんでした:(私はそれが非常にばかげていると信じているので、誰かが何か知っているなら教えてください:Dありがとう!

4

5 に答える 5

5

a構造体のメンバーにアクセスしようとするとt[0]、コンパイラーはこの構造体がどのように見えるかを知る必要があります (たとえば、そのa中にメンバーがあるかどうかを確認するため)。struct testコンパイル時にコンパイラが認識できる場所に型定義を配置しなかった2.cため、エラーが発生します。コンパイラは、 a に何が含まれているかを知りませんstruct test

の定義をstruct testinに配置1.hすると、コンパイラはその型がどのように見えるかを確認し、構造体メンバーを使用できます。

完全な型定義を に入れるだけ1.hです。それが本来あるべき場所です。

于 2011-03-11T16:28:51.357 に答える
3

どこかに、前処理されたファイルがあります

typedef struct test testT;

含まないもの

struct test {
   int a;
};

前処理により、すべての #include ディレクティブがインライン化されます。testT ポインターのみを使用している限り、コンパイラーは「ポインターに相当するメモリーを割り当てる」ことを認識しており、コンパイルは予想以上に進んでいたでしょう。

実際にそのポインターを使用して何かを逆参照しようとすると、コンパイラーは「構造体テスト」の完全な定義が必要であることを認識し、エラーが表示されます。

于 2011-03-11T16:33:37.953 に答える
1

構造体を 1.c と 2.c の両方で使用できるようにする場合は、両方から見えるヘッダー ファイルで定義する必要があります。これが「間違っている」とあなたが言う理由がわかりません。それは一般的な慣行であり、知る限り、それを直接回避する方法は他にありません。

1.c でのみ定義されている場合、コンパイラはstruct test2.c を処理するときに "a" という名前のメンバーがあるかどうかわかりません。

別のオプションは、現在のように前方宣言を維持するだけでなく、ヘッダーにアクセサー/ミューテーター関数も含めることです。その場合、 2.c は の「内部」について知る必要はありませんが、それに基づいstruct testて行動できます。これは、C API でも非常に一般的です。

(1.c と 2.c の両方で同じように構造体を定義することもできますが、それは非常に悪い考えです。)

于 2011-03-11T16:29:43.667 に答える
1

の定義はstruct Test、ファイル 1.c 内でのみ表示されます。コードt[0]->aは、この構造体に という名前のメンバーがあることを認識していませんa。複数のコンパイル ユニット間で共有される型は、ヘッダーで定義する必要があります。

C/C++ は各 .c ファイルを個別にコンパイルするため、構造が他の .c ファイルで定義されていることを知る方法がないことを知っておく必要があります。

おそらく次のことを行う必要があります。

(1.h)

struct test {
    int a;
};
...

(1.c)

#include "1.h"
...

(2.c)

#include "1.h"
...
void funcTest(testT **t, int *size, ..){
    createMem(t,*size); /* void createMem(testT **t, int size); */
    t[0]->a = 0;
    /* ... more code ... */
}
于 2011-03-11T16:30:24.163 に答える
0

しかし、コンパイルされたプログラムを実行すると、エラーが発生する正確な場所は t[0]->a の場所です。

割り当てられたメモリへのポインターは実際には*tではなくt( createMatrixPastebin のコードからわかるように) にあるため、実際に行う必要があります。

(*t)[0].a

そして同様にあなたのforループで:

(*matriz)[i].row
于 2011-03-11T16:33:44.663 に答える