【问题标题】:Why this "dereferencing pointer to incomplete type" error?为什么这个“取消引用指向不完整类型的指针”错误?
【发布时间】:2015-03-20 17:08:41
【问题描述】:

我知道这个问题已经过时了,但我似乎无法理解我的代码有什么问题。

我有一个带有以下struct treetree.c 文件,该文件包含一个头文件,其中声明了指向此类结构的指针:

树.c

#include "tree.h"

typedef struct tree
{
    char desig[200];
    int num;
    tree_ptr left, right, subtree;
} Tree;

树.h

#ifndef ___TREE_H___
#define ___TREE_H___

typedef struct tree *tree_ptr;

#endif

当我尝试在另一个源文件中访问此结构的某些实例时,编译器给我“取消引用指向不完整类型的指针”错误:

insert(..., instance->subtree);

怎么了?

【问题讨论】:

  • 也许调用insert() 的代码看到的是typedef,而不是实际的结构?
  • 最好将你的类型声明移到标题中。
  • 当你在tree.h 中包含treeUser.c 时,问问你自己:编译器是否在treeUser.c 中看到了subtree 的任何提及?还是编译treeUser.csubtree是一个完全未知的概念?
  • 你是说我应该在结构声明之后包含标题?
  • 不要使用以双下划线开头的名称(或者实际上是单下划线)。它们保留供“实现”使用,您会知道您是否正在实现“实现”(但是,提示,如果您不编写 C 编译器及其支持库,那么您就没有实现 '实施”)。

标签: c pointers struct


【解决方案1】:

尝试制作以下您的 tree.h 文件:

   #ifndef  tree_h_
   #define  tree_h_

   typedef struct tree
   {
       char desig[200];
       int num;
       struct tree *left, *right, *subtree;
    } Tree;

   typedef struct tree *tree_ptr;

   #endif

并从您的实现文件中删除 Tree 的声明。由于没有显示小的、工作的 MCVE 或 SSCCE,我无法在您的特定情况下测试上述解决方案,但是以下简单程序编译 (gcc -ansi -pedantic -Wall tr​​ee.c -o tree_test) 没有警告或错误:

文件树.c

    #include <stdio.h>
    #include <stdlib.h>
    #include "tree.h"


    int main(int argc, char* argv[])
    {
         Tree  root;

         root.left = malloc(sizeof(Tree));
         root.right = malloc(sizeof(Tree));
         root.subtree = NULL;

         if((NULL != root.left) && (NULL != root.right))
         {
             root.left->left = NULL;
             root.left->left = NULL;

             root.right->left = NULL;
             root.right->right = NULL;
         }

         return 0;
    }

这是在 Centos 7 系统上使用 gcc 版本 4.8.2 测试的。

注意我只提供了最简单的错误检查,没有错误处理和清理代码来保持示例的简短。当然,在您的代码中,您应该确保完整的错误检查、错误处理和清理。

【讨论】:

    【解决方案2】:

    您的头文件只有指针类型“tree_ptr”的定义。指针在 32 位机器上总是 4 个字节,无论它们指向什么。因此,只要您不访问“struct tree”的成员就可以了,即当您将值分配给“tree_ptr”类型的指针或检查“tree_ptr”类型的指针是否不为 NULL 时。这类操作不需要完整的结构定义。但是如果你想访问这个结构的成员,你的代码需要范围内的结构定义。结构不像函数,所以你不能在头文件中声明它们并在 .c 文件中定义它们。所以我建议你将你的结构定义移动到你的头文件中。

    【讨论】:

      【解决方案3】:

      其他源文件无法看到您的tree.c,并且完全不知道您的tree.c 中的内容。他们只能看到tree.h 声明

      typedef struct tree *tree_ptr;
      

      这将struct tree 声明为不完整类型。

      您的struct treetree.c 内部的完整类型,并且仅在tree.c 内部。在所有其他 .c 文件中,它是不完整的类型。如果您希望它在包含tree.h 的所有源文件中完整,则必须将struct tree 的完整声明移动到tree.h

      【讨论】:

        猜你喜欢
        • 2011-04-06
        • 2018-05-31
        • 2017-11-02
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 2011-12-15
        相关资源
        最近更新 更多