开发者

I can't use sizeof(struct hsearch_data) from <search.h>

开发者 https://www.devze.com 2023-02-12 19:27 出处:网络
I\'m working on an open-source project, and there is an hash_table that I need to change for a more efficient hash_table, so, I\'m trying

I'm working on an open-source project, and there is an hash_table that I need to change for a more efficient hash_table, so, I'm trying to use the header <search.h>;

The problem, is that I need to overwrite the functions that is already being used all over the project ... but for that, I need to use sizeof(struct hsearch_data) 开发者_StackOverflowbut it doesn't work.

Follow the code:

#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: in the header file, there is a typedef struct hsearch_data hash_table;

I got the error message:

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

Can anybody help me out?


Even though I still have some trouble with hash_table, I solved this specific problem:

it's something silly ... the

#define _GNU_SOURCE

must be the first thing in the file ... I'm not sure about why you have to do that ... but it works.

Some people said something about __USE_GNU, this flag is set automatically when you use #define _GNU_SOURCE

And I changed the malloc to calloc, it was a good idea!


Apparently, the trouble is that the <search.h> header on your platform does not define the structure type. As noted in a comment to the question, on a RHEL5 Linux machine, the defines 'struct hsearch_data' when __USE_GNU is defined, which is, in turn, defined when _GNU_SOURCE is defined as you have it. However, not all machines are Linux. I note that POSIX does define the <search.h> header, but does not specify the structure you are seeking to use.

You will need to track down where the project defines the structure, and decide how you can make that available to this code. It may be simple - if the structure is safely segregated in a header which can be safely included. It may be complex if the header that defines the structure also defines other things which you can't use.

Since you are trying to preserve the same interface as the original code, you should be aiming to use the original header to provide the correct interface definition.


At a guess, you're not supposed to use hsearch_data yourself, but pointers to hsearch_data objects. Consequently, the header search.h would not expose its definition, merely a forward declaration. You are then not able to find its size.

If true, the library is designed for you to use the functions it provides, rather than rolling your own by stealing its datatypes.


The reentrant versions with _r are GNU extensions to the hash functions in "search.h". If you look into the include file you'd see that they are protected by a macro name __USE_GNU that doesn't seem to be documented, but that you probably have to set to use them properly. In particular your sizeof should then work.

But:

  • your malloc should not be casted. In C you don't do that, void* can be assigned to any pointer to object.
  • the line following your malloc will not work as you wrote it. This is initializer syntax and not for assignment.
  • what they mean by zeroing out the initial table for hcreate_r is probable to use calloc instead of malloc
  • if you want to do an "absolutely safe" initialization that and have a C99 conforming compiler (e.g gcc or clang) you could do the following assignment with a compound literal *table = (struct hsearch_data){0};
0

精彩评论

暂无评论...
验证码 换一张
取 消