access element of struct passed into a void* pointer

烈酒焚心 提交于 2019-12-18 07:01:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!