简体   繁体   English

取消引用指向不完整类型“结构名称”的指针

[英]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' .我想显示列表的大小,但它显示错误: dereferencing pointer to incomplete type 'struct List'

main.c : main.c

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

dlist.c : 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: 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".您似乎正在导入“dlist.h”,而所有声明都出现在实现文件AKA“dlist.c”中。

You should place your visible declarations to the ".h" file.您应该将可见的声明放到“.h”文件中。 And not only types - function declaration too.不仅是类型 - function 声明也是如此。

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 .通过在 header 中声明结构类型但不包括其定义(即其成员列表),您创建了一个不透明类型 Because code outside of dist.c does not have the definition, it cannot declare objects of that type or access their members.因为dist.c之外的代码没有定义,所以它不能声明该类型的对象或访问它们的成员。 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.这就是为什么编译器不会 object 直到它到达printf调用,其第二个参数是一个表达式,它试图访问一个struct List的成员,其定义在 Z31A1FD140BE4BEF2D11E121EC9A18A58 中不可见

There are two possible directions to go from here.从这里到 go 有两个可能的方向。 One would be to move the definition of struct List into dist.h , and probably also that of struct Node .一种是将struct List的定义移动到dist.h中,可能还有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. dist.c然后将#include header 来获取这些,就像其他人一样,并且在main()中,您将能够直接访问结构成员,就像您尝试做的那样。

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.这将在 dist.c 中的go与您的Create() function 一起声明,并在dist.h中声明,并将您的main()

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).说到您的Create() function,它被错误地命名为损坏,并且您对它的使用不正确(综合起来,我最初将其称为损坏)。 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.您目前正在向它传递一个未初始化的指针,这是无用的,它是导致Create()然后尝试通过该指针访问 object 时出现的未定义行为的关键因素。

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.初始化 function(例如您的Create()是可以的,并且可以使用任何一种方法,但是对于不透明类型的方法,您确实需要真正的实例创建 function,因为您不能声明不透明类型的对象。 Such a function would typically return a pointer to the created object.这样的 function 通常会返回指向创建的 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.对于这样的 function 来说,执行初始化是很自然的,并且在许多情况下,这将讨论单独的仅初始化 function。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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