3

大家好!

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

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

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

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

我有一个 1.h 有 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 谢谢!

4

5 回答 5

5

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

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

只需将完整的类型定义放入1.h,这就是它应该在的地方。

于 2011-03-11T16:28:51.357 回答
3

某处你有一个预处理文件

typedef struct test testT;

其中不包括

struct test {
   int a;
};

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

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

于 2011-03-11T16:33:37.953 回答
1

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

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

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

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

于 2011-03-11T16:29:43.667 回答
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 ... */
}
于 2011-03-11T16:30:24.163 回答
0

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

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

(*t)[0].a

同样在你的for循环中:

(*matriz)[i].row
于 2011-03-11T16:33:44.663 回答