我正在开发一个开源项目,并且有一个hash_table
我需要更改为更高效的hash_table,所以,我正在尝试
使用标题<search.h>
;
问题是,我需要覆盖已经存在的功能 在整个项目中使用...但为此,我需要使用sizeof(struct hsearch_data) 但它不起作用。
按照代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _GNU_SOURCE
#include <search.h>
#include "hashtable.h"
#define MAX_ELEMENTS 100
#define ERROR 2
#define SUCCESS 0
hash_table *new_hash_table()
{
hash_table *table = (hash_table *) malloc(sizeof(struct hsearch_data));
*table = {0};
int status = hcreate_r(MAX_ELEMENTS, table);
if (status == 0) {
hdestroy_r(table);
return NULL;
}
return table;
}
PS:在头文件中,有一个 typedef struct hsearch_data hash_table;
我收到了错误消息:
hashtable.c: In function ‘new_hash_table’:
hashtable.c:18: error: invalid application of ‘sizeof’ to incomplete type ‘struct hsearch_data’
hashtable.c:19: error: dereferencing pointer to incomplete type
有人可以帮帮我吗?
答案 0 :(得分:2)
显然,问题是平台上的<search.h>
标头没有定义结构类型。正如对问题的评论中所述,在RHEL5 Linux机器上,定义struct hsearch_data
时定义__USE_GNU
',而_GNU_SOURCE
定义为<search.h>
时定义为{{1}}有它。但是,并非所有机器都是Linux。我注意到POSIX确实定义了{{1}}标题,但未指定您要使用的结构。
您需要跟踪项目定义结构的位置,并决定如何使该代码可用。这可能很简单 - 如果结构安全地隔离在一个可以安全包含的标题中。如果定义结构的标题还定义了您不能使用的其他内容,则可能很复杂。
由于您尝试保留与原始代码相同的接口,因此您应该使用原始标头来提供正确的接口定义。
答案 1 :(得分:2)
猜测一下,你不应该自己使用hsearch_data
,而是指向hsearch_data
个对象。因此,标题search.h
不会公开其定义,只是前向声明。然后你无法找到它的大小。
如果为true,则该库旨在让您使用它提供的函数,而不是通过窃取其数据类型来自行编译。
答案 2 :(得分:1)
_r
的可重入版本是“search.h”中哈希函数的GNU扩展。如果您查看包含文件,您会看到它们受到宏名称__USE_GNU
的保护,但似乎没有记录,但您可能必须设置为正确使用它们。特别是您的sizeof
应该有效。
但是:
malloc
不应该被投放。
在C中你不这样做,void*
可以
被分配给任何指向对象的指针。malloc
之后的行
不像你写的那样工作。这是
初始化器语法而不是
分配hcreate_r
的初始表归零可能意味着使用calloc
代替malloc
*table = (struct hsearch_data){0};
答案 3 :(得分:1)
即使我认为hash_table
仍有问题,我也解决了这个具体问题:
这是愚蠢的......
#define _GNU_SOURCE
必须是文件中的第一件事...我不确定你为什么要这样做......但它确实有效。
有些人对_USE_GNU
说了些什么,当你使用#define _GNU_SOURCE
时会设置这个标志
我将malloc
更改为calloc
,这是一个好主意!
TKS。