【问题标题】:Dereferencing pointer to incomplete type when providing function pointer提供函数指针时取消引用指向不完整类型的指针
【发布时间】:2018-02-06 00:42:42
【问题描述】:

当我尝试运行以下代码时,我收到指向不完整类型错误的取消引用指针。我检查了有关此错误的其他几个问题,据我所知,这不是由于缺少或额外的 struct 关键字,我相信指针类型是正确的,但我可能弄错了。

代码可能还有其他问题,因为我刚刚学习 C,我很高兴自己尝试解决这些问题我似乎无法找到不完整类型错误的问题。

Development/C/AI/test/src/test.c: In function ‘compare’:
Development/C/AI/test/src/test.c:10:19: error: dereferencing pointer to incomplete type ‘lrgraph_node {aka struct lrgraph_node}’
  if ( strcmp(other->dataType, current->dataType == 0) ) {

test.c

#include "lrGraph.h"
#include <string.h>

int data = 1;
char *dataType = "int";
lrgraph_edge *connected[] = {};
unsigned numEdges = 0;

int compare( lrgraph_node *other, lrgraph_node *current ) {
    if ( strcmp(other->dataType, current->dataType == 0) ) {
        return (int)other->data - (int)current->data;
    }
    return -1;
}

int main() {
    lrgraph_node *nodeA = lrgraph_createNode((void*)&data, dataType, &compare, connected, numEdges);
    lrgraph_printVersion();
}

lrGraph.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lrGraph.h"

struct lrgraph_edge {
    float weight;
    lrgraph_node *nodeA;
    lrgraph_node *nodeB;
};

struct lrgraph_node {
    //data can be of any type
    void *data;
    //string to see if this node can be compared to another node based on data type
    char *dataType;
    int numEdges;
    //comparator function which compares another node to this node
    int (*compare)(lrgraph_node *other, lrgraph_node *current);
    //array of connected edges
    lrgraph_edge *connected[];
};

void lrgraph_printVersion() {
    fprintf(stdout, "\nlrgraph version 0.01b\n");
}


lrgraph_node* lrgraph_createNode(void *data, char *dataType, int (*compare)(lrgraph_node* other, lrgraph_node* current), lrgraph_edge *connected[], unsigned numEdges) {
    //allocate enough memory for the struct plus each pointer in the array of edges - https://stackoverflow.com/questions/32311269/can-we-have-a-struct-element-of-type-variable-length-array
    lrgraph_node *node = malloc(sizeof(lrgraph_node) + numEdges * sizeof(lrgraph_edge));
    if (NULL != node) {
        node->data = data;
        node->dataType = strdup(dataType);
        node->compare = compare;
        node->numEdges = numEdges;
        //initialize each edge in the array
        for( unsigned i=0; i < numEdges; i++) {
            node->connected[i] = connected[i];
        }
    }
    return node;
}

lrGraph.h

#ifndef LRGRAPH_H
#define LRGRAPH_H

typedef struct lrgraph_node lrgraph_node;

typedef struct lrgraph_edge lrgraph_edge;

lrgraph_node* lrgraph_createNode(void *data, char *dataType, int (*compare)(lrgraph_node *other, lrgraph_node *current), lrgraph_edge *connected[], unsigned numEdges);

void lrgraph_printVersion();

#endif /*LRGRAPH_H*/

【问题讨论】:

  • 没有lgraph_node的定义。它是在任何地方定义的吗?
  • lrGraph.h 和 lrGraph.c,除非我定义不正确,这就是问题所在
  • 您将类型定义放在lrGraph.c 中。类型仅在lrGraph.c 中完整。在所有其他 .c 文件中,它们是不完整的。为什么将类型定义放在lrGraph.c 中?如果您希望您的类型在多个 .c 文件中是完整的,那么定义必须在所有这些 .c 文件中很容易,即它们应该驻留在头文件中。
  • 您的compare 需要知道lrgraph_node 的完整且准确的定义,而它没有(标头仅声明typedef,而不是实际的struct)。换句话说,错误是完全正确的,您的代码部分类型不完整。
  • 你确定你不是说strcmp(other-&gt;dataType, current-&gt;dataType) == 0

标签: c struct function-pointers


【解决方案1】:

“不完整类型”表示编译器看到您正在尝试使用结构类型,但该结构没有定义。

如果您只使用指向结构的指针(实际上是在 C 中实现抽象数据类型的方式),这很好,但如果您想取消引用这样的指针,结构定义必须是可见的。

test.c 中只有lrGraph.h 的内容是可见的(即typedef struct lrgraph_node lrgraph_node;),但实际的struct lrgraph_node { ... }; 定义只存在于lrGraph.c 中。

可能的解决方案:将struct lrgraph_node { ... } 定义移动到标题中。 (或者,将compare 的定义放入lrGraph.c)。

【讨论】:

  • 感谢这回答了为什么存在问题,但是 C 中有没有办法隐藏结构的实现,同时允许用户传递一个函数供该结构使用?我试图在这里做类似 qsort 的事情,用户在创建节点时提供比较器
  • @SMC 如果您在lrGraph.c 中创建返回节点指针的datadataType 的函数(并在lrGraph.h 中声明它们),您可以在@987654333 中使用这些函数@。您可能还需要图形遍历函数,以及您希望其他人能够做的任何其他事情的函数。
猜你喜欢
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多