how to use void ** pointer correctly?

前端 未结 4 2008
滥情空心
滥情空心 2020-12-07 23:24

I am trying to use a double void pointer but I am a little bit confused about the usage. I have a struct that contains a void ** array

相关标签:
4条回答
  • 2020-12-07 23:38

    The fact you are working with void* and void** doesn't matter, pointer arithmetic still works fine, so both options you wrote are correct.

    Here's an example:

    struct Thing
    {
        void ** array;
    };
    
    struct Object
    {
        int i;
        char c;
    };
    
    int main ()
    {
    
        struct Thing * c = malloc (sizeof(struct Thing));
        c->array = malloc(10 * sizeof(void*));
    
        struct Object * o = malloc (sizeof(struct Object));
        o->i = 2; o->c = 'a';
    
        *(c->array + 2) = o;
    
        printf("Object: i = %d, c = %c\n", ((Object*)c->array[2])->i, ((Object*)c->array[2])->c);
    
        free(o);
        free(c->array);
        free(c);
        return 0;
    }
    

    Since it's void* you can put there pointer to whatever, just don't forget it to cast to original type before using it ;)

    0 讨论(0)
  • 2020-12-07 23:50

    One quick hint about pointers: if you are casting it, you are probably doing something wrong.

    As for your question. I am not sure what item is in your problem. In your first part you've already discovered how to acces a member in your array. You could simply use it:

    void *get_item(Thing *c, int index)
    {
        return *(c->array + index); // or return c->array[index];
    }
    

    If you need the address of the pointer at index:

    void **get_item_cell(Thing *c, int index)
    {
        return c->array + index; // or return &c->array[index];
    }
    

    In the second part, you don't dereference the pointer (for + option), or take the address of array result, since it automatically dereferences it.


    EDIT: I think I now know what you want. You have a function similar to my second one above, but it is:

    void *get_item_cell(Thing *c, int index)
    {
        return (void *)(c->array + index);
    }
    

    You want to dereference the value returned from this function, and access the object. In that case, you can only use Option 4 safely. Since you don't have the index, you cannot move to any other cell (you don't know if you are at the end of the array, or at the beginning - so no additions or subtractions). You can only fix the mistake of the above function: cast to void **, and then dereference it: *(void **)item. This will give you a void *. If you want to access the object pointed from this cell, you need to cast that to the correct type as well: some_object_ptr *obj = *(void**)item.

    0 讨论(0)
  • 2020-12-07 23:51

    A void ** is just a pointer to a pointer to memory with an unspecified type. You can only dereference it once (since you can't dereference a void *). However, apart from that, it is basically like any other pointer type. If it helps you, think of it the same way as you would with int *.

    So, in your specific situation, we have:

    void** array;
    int arrayLen = 10;
    array = (void**)malloc(arrayLen * sizeof(void*));
    
    some_type_t* some_object_ptr;    
    // The following two assignment are equivalent since in C,
    // array[index] <=> *(array + index)
    array[index] = (void*)some_object_ptr;
    *(array + index) = (void*)some_object_ptr;
    

    Then array is a pointer to the whole array, while *array is a pointer to the first element, since it is equivalent to array[0].

    0 讨论(0)
  • 2020-12-07 23:58

    Almighty push!

    any_type x ;
    void * v = * ( void * * ) & x ;
    

    almighty pull!

    void * v ;
    any_type x = * ( any_type * ) & v ;
    

    beware of losing/gaining digits

    0 讨论(0)
提交回复
热议问题