2017-08-28 54 views
1

当我尝试运行以下代码时,我得到了不完整类型错误的取消引用指针。我已经检查了几个关于这个错误的其他问题,从我能告诉它不是由于缺少或额外的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*/ 
+1

没有'lgraph_node'的定义。它在任何地方定义? –

+0

lrGraph.h和lrGraph.c,除非我定义不正确,那就是问题 – SMC

+2

您将类型定义放在'lrGraph.c'中。这些类型只在'lrGraph.c'中完成。在所有其他'.c'文件中,它们是不完整的。为什么你把你的类型定义放在'lrGraph.c'中?如果你想让你的类型在多个'.c'文件中完成,那么所有这些'.c'文件中的定义都应该很容易,即它们应该驻留在头文件中。 – AnT

回答

4

“不完全类型” 指的是编译器看到你想使用结构类型,但没有定义该结构克拉。

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

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

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

+0

谢谢这回答为什么问题存在,但有没有办法在C隐藏结构的实现,同时允许用户传递一个函数该结构使用?我试图做一些像qsort这样的地方,用户在创建节点时提供一个比较器 – SMC

+1

@SMC如果你在'lrGraph.c'中创建函数,它返回一个节点指针的'data'和'dataType'(并声明它们在'lrGraph.h'中,你可以在'test.c'中使用这些函数。您可能还需要图形遍历函数,并为其他任何您希望其他人能够完成的功能。 –

相关问题