【问题标题】:Error: In C, got the error "dereferencing pointer to incomplete type" in a struct pointer错误:在 C 中,结构指针中出现错误“取消引用指向不完整类型的指针”
【发布时间】:2011-07-13 15:04:23
【问题描述】:

大家好!

我在尝试测试 Clever Frog 游戏的代码时遇到以下错误: 错误:取消引用指向不完整类型的指针

“完整代码”位于 pastebin.com - here(不会过期)。但是我认为通过下面的解释,任何人都可以理解。注意:我还没有实现擦除分配的内存和其他东西的功能。

我在 1.c 文件中定义了一个结构:

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

我有一个 1.h wicth 有 typedef 使用它:

...
typedef struct test testT;
...

然后我有一个函数,其中有一个取决于 testT 的参数,它在 2.c 中:

...
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 文件中使用 struct test 时,代码会编译(从 1.c 中删除 struct test - 这是错误的)。但是,在运行编译好的程序时,错误发生的地方正是t[0]->a的地方。

我已经尝试了“一切”但没有任何效果:(我相信这是非常愚蠢的事情,所以如果有人知道一些事情,请告诉我:D 谢谢!

【问题讨论】:

  • EDIT “奇怪的是,当我在 1.h 文件中使用 struct test 时,代码会编译(从 1.c 中删除 struct test - 这是错误的)。但是,运行编译后的程序时,出错的地方就是t[0]->a的地方。"错误是“分段错误”。

标签: c pointers header struct dereference


【解决方案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 ... */
}

【讨论】:

  • 是的,是这样的,看看:pastebin.com/ZbudbbVE 不过还是,错误在这里>_
  • @Shuryon:不,不是这样:你的代码中positionLeaf的定义在matriz.c,而不是matriz.h!
  • Uhn.. 程序以这种方式编译,但在运行程序时会在 matriz[i]->row 处获得 segmentation faultfor循环
  • @Shuryon:它不能在我身边编译。我贴了日志here
  • @Shuryon:或者你的意思是它按照我的方式编译?能否请您粘贴段错误的代码?
【解决方案2】:

但是,在运行编译后的程序时,出错的地方就是t[0]->a的地方。

指向已分配内存的指针实际上是在*t,而不是t(从您在Pastebin 的createMatrix 代码中可以看出),所以您真的应该这样做:

(*t)[0].a

同样在你的for循环中:

(*matriz)[i].row

【讨论】:

  • uhn.. 出现另一个错误:error: invalid use of undefined type ‘struct positionLeaf’
  • @Shuryon:嗯,你混淆了两种不同的错误。我的回答是关于运行时错误,你得到的是编译时错误(其他人已经讨论过)。
【解决方案3】:

你有一个预处理文件的地方

typedef struct test testT;

不包括

struct test {
   int a;
};

预处理内联所有#includes 指令。只要您只使用一个 testT 指针,编译器就会知道“分配一个指针的内存价值”,并且编译会比预期的更进一步。

当您实际尝试使用该指针取消引用某些内容时,编译器随后会意识到它需要“struct test”的完整定义,并且您会显示错误。

【讨论】:

  • 您的意思是我需要包含正确的 *.h,对吗?但它是(我认为),所以我不知道该怎么做。看一看:pastebin.com/ZbudbbVE
【解决方案4】:

如果您希望结构在 1.c 和 2.c 中都可用,则必须在两者都可见的头文件中定义它。我不知道你为什么说这是“错误的”,这是常见的做法,AFAIK 没有其他办法直接解决这个问题。

如果只在 1.c 中定义,那么编译器在处理 2.c 时不知道struct test 是否有一个名为“a”的成员。

另一种选择是只保留你现在的前向声明,但也在标题中包含访问器/修改器函数。然后 2.c 不必知道struct test 的“内部”,但可以对其采取行动。这在 C API 中也很常见。

(您也可以在 1.c 和 2.c 中定义相同的结构,但这是一个非常坏主意。)

【讨论】:

  • "1.h" 不包含struct test 的定义。它只说“某处有一个结构测试”并为该类型定义了另一个名称。就这样,当查看"2.c" 时,编译器不知道struct test 实际上是什么,所以它只能用它做不需要任何结构知识的事情(比如处理指向它的指针)。 struct test 在这一点上是“不透明类型”。您可能需要搜索该词以查找更多信息。
【解决方案5】:

当您尝试访问t[0] 结构的a 成员时,编译器需要知道该结构的外观(例如,查看其中是否有任何a 成员)。由于您没有将struct test 类型定义放在编译器在编译2.c 时可以看到的任何地方,因此您会收到错误消息。编译器不知道 struct test 包含什么。

如果将struct test 的定义放在1.h 中,编译器会看到该类型的外观并可以使用结构成员。

只需将完整的类型定义放在1.h 中即可。

【讨论】:

  • 关于struct test 的正确位置我认为它在*.c 和typedef 在*.h Uhn.. 当我这样做时,我得到segmentation fault 的位置t[0]->a = 0我应该说在 od0 的地方,它将从用户的输入中获取一个值;这里:pastebin.com/ZbudbbVE
  • @Shuryon:正确的位置在 *.h 中。关于分段错误:可能这意味着 createMem 实际上并没有将 t[0] 设置为指向有用的东西。
猜你喜欢
  • 2014-07-06
  • 2016-07-12
  • 2018-05-31
  • 2017-11-02
  • 1970-01-01
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 2011-04-06
相关资源
最近更新 更多