web-dev-qa-db-ja.com

Cプログラミング:不完全型エラーへのポインターの逆参照

私は次のように定義された構造体を持っています:

struct {
 char name[32];
 int  size;
 int  start;
 int  popularity;
} stasher_file;

およびそれらの構造体へのポインターの配列:

struct stasher_file *files[TOTAL_STORAGE_SIZE];

私のコードでは、構造体へのポインターを作成し、そのメンバーを設定して、配列に追加しています。

 ...
 struct stasher_file *newFile;
 strncpy(newFile->name, name, 32);
 newFile->size = size;
 newFile->start = first_free;
 newFile->popularity = 0;
 files[num_files] = newFile;
 ...

次のエラーが表示されます。

エラー:不完全な型へのポインターの逆参照

newFile内のメンバーにアクセスしようとするたびに。何が間違っていますか?

38
confusedKid

最初の定義でstruct stasher_fileを定義していません。定義したのは、nameless structタイプと、そのタイプの変数stasher_fileです。コードにはstruct stasher_fileなどのタイプの定義がないため、コンパイラは不完全なタイプについて文句を言います。

struct stasher_fileを定義するには、次のようにする必要があります。

struct stasher_file {
 char name[32];
 int  size;
 int  start;
 int  popularity;
};

定義内のstasher_file名の場所に注意してください。

47
AnT

ポインターnewFileを使用しますが、スペースを割り当てません。

struct stasher_file *newFile = malloc(sizeof(stasher_file));

また、構造体名を上部に配置する必要があります。 stasher_fileを指定した場所は、その構造体のインスタンスを作成することです。

struct stasher_file {
    char name[32];
    int  size;
    int  start;
    int  popularity;
};
13
Brian R. Bondy

実際にどのように構造を定義しましたか?もし

struct {
  char name[32];
  int  size;
  int  start;
  int  popularity;
} stasher_file;

型定義と見なされるため、typedefがありません。上記のように記述した場合、実際にはstasher_fileという変数を定義します。この変数の型は匿名の構造体型です。

試して

typedef struct { ... } stasher_file;

(または、他の人が既に述べたように):

struct stasher_file { ... };

後者は実際にタイプの使用に一致します。最初の形式では、変数宣言の前にstructを削除する必要があります。

10
Dirk

上記のケースは新しいプロジェクト用です。よく確立されたライブラリのフォークを編集しているときに、このエラーが発生しました。

typedefは編集中のファイルに含まれていましたが、構造体は含まれていませんでした。

最終結果は、間違った場所で構造体を編集しようとしたことです。

同様の方法でこれに遭遇した場合は、構造体が編集されている他の場所を探し、そこで試してください。

5
Pete Brumm

このエラーが発生する理由は、structを次のように宣言したためです。

struct {
 char name[32];
 int  size;
 int  start;
 int  popularity;
} stasher_file;

これはstasher_file型を宣言していません。これは匿名struct型を宣言しており、stasher_fileという名前のグローバルインスタンスを作成しています。

あなたが意図したものは:

struct stasher_file {
 char name[32];
 int  size;
 int  start;
 int  popularity;
};

ただし、Brian R. Bondyの応答はエラーメッセージについては正しくありませんでしたが、スペースを割り当てずにstructに書き込もうとしているのは正しいことです。 struct stasher_file構造体へのポインターの配列が必要な場合は、mallocを呼び出して、それぞれにスペースを割り当てる必要があります。

struct stasher_file *newFile = malloc(sizeof *newFile);
if (newFile == NULL) {
   /* Failure handling goes here. */
}
strncpy(newFile->name, name, 32);
newFile->size = size;
...

(ところで、strncpyを使用するときは注意してください。NULで終了する保証はありません。)

1
jamesdlin