Программирование на C: разыменование указателя на неполный тип ошибки - PullRequest
37 голосов
/ 05 апреля 2010

У меня есть структура, определенная как:

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. Что я делаю не так?

Ответы [ 5 ]

47 голосов
/ 05 апреля 2010

Вы не определили struct stasher_file своим первым определением. Вы определили тип структуры без имени и переменную stasher_file этого типа. Поскольку в вашем коде нет определения такого типа, как struct stasher_file, компилятор жалуется на неполный тип.

Чтобы определить struct stasher_file, вы должны были сделать это следующим образом

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

Обратите внимание, где имя stasher_file находится в определении.

13 голосов
/ 05 апреля 2010

Вы используете указатель newFile без выделения места для него.

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

Также вы должны поместить имя структуры вверху. Вы указали stasher_file для создания экземпляра этой структуры.

struct stasher_file {
    char name[32];
    int  size;
    int  start;
    int  popularity;
};
10 голосов
/ 05 апреля 2010

Как вы на самом деле определили структуру? Если

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

принимается как определение типа, в нем отсутствует typedef. Когда написано, как указано выше, вы фактически определяете переменную с именем stasher_file, тип которой является неким анонимным типом структуры.

Попробуйте

typedef struct { ... } stasher_file;

(или, как уже упоминалось другими):

struct stasher_file { ... };

Последний действительно соответствует вашему использованию типа. Первая форма потребует, чтобы вы удалили struct до объявления переменных.

5 голосов
/ 11 мая 2011

случай выше для нового проекта. Я столкнулся с этой ошибкой при редактировании форка хорошо зарекомендовавшей себя библиотеки.

typedef был включен в файл, который я редактировал, но структура не была.

Конечным результатом было то, что я пытался отредактировать структуру в неправильном месте.

Если вы столкнетесь с этим подобным образом, поищите другие места, где редактируется структура, и попробуйте там.

1 голос
/ 05 апреля 2010

Причина, по которой вы получаете эту ошибку, заключается в том, что вы объявили 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;
};

Но учтите, что покаОтвет Брайана Р. Бонди был неверным по поводу вашего сообщения об ошибке, он прав, что вы пытаетесь записать в 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-прекращение.)

...