简体   繁体   中英

dereferencing pointer to incomplete type ‘struct name’

I am trying to write a doubly linked linear list. I want to display the size of the list, but it displays an error: dereferencing pointer to incomplete type 'struct List' .

main.c :

#include "dlist.h"
#include <stdio.h>
    int main(){
        struct List* l;
        Create(l);
        printf("%d", *(l->size));
        return 0;
}

dlist.c :

typedef int T;
struct Node{
        struct Node* prev;
        struct Node* next;
        T data;
};
struct List {
        struct Node* head;
        int size;
};
void Create(struct List* l){
        l->head = (struct Node*)malloc(sizeof(struct Node));
        l->head->next = NULL;
        l->head->prev = NULL;
        l->size = 0;
}

dlist.h:

typedef int T;
struct Node;
struct List;
void Create(struct List* Item);

You seem to be importing "dlist.h" while all the declarations appear in the implementation file AKA "dlist.c".

You should place your visible declarations to the ".h" file. And not only types - function declaration too.

By declaring the structure type in your header but not including its definition there (that is, its member list), you have created an opaque type . Because code outside of dist.c does not have the definition, it cannot declare objects of that type or access their members. The type is opaque to such code.

But it can create and deal in pointers to objects of that type, which does not require information about the size or members of that type. This is why the compiler does not object until it reaches the printf call, whose second argument is an expression that attempts to access a member of a struct List , whose definition is not visible in that scope.

There are two possible directions to go from here. One would be to move the definition of struct List into dist.h , and probably also that of struct Node . dist.c would then #include that header to get those, just like everyone else, and in main() you would be able to access the structure members directly, as you are trying to do.

The other way, used when a type is intentionally made opaque, is to provide appropriate functions for operating on objects of your type, for example:

int get_size(struct List *list) {
    return list->size;
}

That would go in dist.c alongside your Create() function, with a declaration in dist.h , and your main() would call it to get the list size.

And speaking of your Create() function, it is broken misleadingly named, and your usage of it is incorrect (which, combined, led me initially to call it broken). You are presently passing an uninitialized pointer to it, which is useless, and which is a key contributor to the undefined behavior that arises when Create() then attempts to access an object through that pointer.

An initialization function such as your Create() is ok, and can work with either approach, but for the opaque type approach you do need a bona fide instance creation function, since you cannot declare objects of an opaque type. Such a function would typically return a pointer to the created object. It would be natural for such a function also to perform initialization, and in many cases that would moot a separate initialization-only function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM