问题
I'm working with a binary search tree data structure to sort a series of structs with the type definitions:
typedef struct {
char c;
int index;
} data_t;
typedef struct node node_t;
typedef node {
void *data;
node_t *left;
node_t *right;
}
The node_t typedef is from a library provided to me for this purpose, presumably with a void* pointer to ensure polymorphism. node
will be passed into the function:
static void
*recursive_search_tree(node_t *root,
void *key, int cmp(void*,void*))
Within the recursive_search_tree function, I want to be able to modify the code to use the index element as a condition to find the match closest to the index of the linear pass over an array of characters, which would ultimately involve a data_t being passed into *key
and key->index
being accessed within the function.
The Question
Is it possible to access key->index
where key is a void*
pointing to a data_t
struct, or would this only be possible if data_t
was declared as the type for key? I have tried to do the latter, however even casting the pointer to an int doesn't seem to pass the compiler.
回答1:
Sure it's possible, you'd cast key
as type *data_t
. (As long as that's really what key
points to!)
key /* argument of type void* */
(data_t*)key /* cast as type data_t* */
((data_t*)key)->index /* dereferenced */
Here is a simple example:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
char c;
int index;
} data_t;
typedef struct node {
void *data;
struct node *left;
struct node *right;
} node_t;
static int cmp(void *lhs, void *rhs)
{
return ((data_t *)lhs)->index - ((data_t *)rhs)->index;
}
int main(void)
{
data_t d0;
data_t d1;
d0.c = 'A';
d0.index = 1;
d1.c = 'B';
d1.index = 2;
printf("d0 < d1? %s\n", (cmp((void *)&d0, (void *)&d1) < 0 ? "yes" : "no"));
printf("d1 < d0? %s\n", (cmp((void *)&d1, (void *)&d0) < 0 ? "yes" : "no"));
return EXIT_SUCCESS;
}
回答2:
This is type unsafe, as is any use of void. The use of void is generally because the intermediate is holding onto something it doesn't use for someone else's convenience. This is a C function to let you hold whatever you want in a tree. All it does is return whatever pointer you give it.
In your search function
int cmp(void* dt1, void* dt2)
{
data_t* data1 = (data_t*)dt1;
data_t* data2 = (data_t*)dt2;
/* Do what you need with data1 and data2 here */
}
Should let you do whatever you need. The problem you have is you need to cast your values inside the function. The parameters to cmp should exactly match the API for the library you are using, which says void* for the parameters.
来源:https://stackoverflow.com/questions/12995287/access-element-of-struct-passed-into-a-void-pointer