我不能使用<search.h> </search.h>中的sizeof(struct hsearch_data)

时间:2011-02-20 18:57:04

标签: c search hashtable sizeof

我正在开发一个开源项目,并且有一个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

有人可以帮帮我吗?

4 个答案:

答案 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
  • 如果你想做一个“绝对安全”的初始化有一个符合C99的编译器(例如gcc或clang)你可以用复合文字进行以下赋值 *table = (struct hsearch_data){0};

答案 3 :(得分:1)

即使我认为hash_table仍有问题,我也解决了这个具体问题:

这是愚蠢的......

#define _GNU_SOURCE

必须是文件中的第一件事...我不确定你为什么要这样做......但它确实有效。

有些人对_USE_GNU说了些什么,当你使用#define _GNU_SOURCE时会设置这个标志

我将malloc更改为calloc,这是一个好主意!

TKS。