如何正确使用void **指针?
我试图使用双void
指针,但我对使用有点困惑。 我有一个包含void **
数组的结构。
struct Thing{ void ** array; }; struct Thing * c = malloc (sizeof(struct Thing)); c->array = malloc( 10 * sizeof(void *) );
所以如果我想为每个指针分配一个不同的对象并尝试检索该值
// Option 1 *(c->array + index) = (void *) some_object_ptr; // Option 2 c->array[index] = (void *) some_object_ptr;
然后,我有另一个函数给出(void *) item
指向每个单元格,而不是some_object_ptr
。
如果我想检索some_object_ptr
指向的值,
我应该这样做
function return type is 'void *' and takes argument 'void *' // Option 3 return (void**) item // Option 4 return *((void**)item)?
奇怪的是,当我使用数组时,数组下标方法我不能使用选项4,只有选项3; 当我使用*(c->array + index)
我只能使用opt.4。 而不是选择。 ..
有人可以告诉我这件事吗? 如果我做出任何无效的假设,那么请你纠正我吗?
void **
只是一个指向指向具有未指定类型的内存的指针的指针。 你只能解除引用一次(因为你不能取消引用空格void *
)。 但是,除此之外,它基本上与任何其他指针类型一样。 如果它对你有所帮助,那么就像使用int *
。
所以,在您的具体情况下,我们有:
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;
然后, array
是指向整个数组的指针,而*array
是指向第一个元素的指针,因为它等同于array[0]
。
关于指针的一个快速提示:如果你正在施法,你可能做错了什么。
至于你的问题。 我不确定你的问题是什么item
。 在您的第一部分中,您已经发现了如何访问arrays中的成员。 你可以简单地使用它:
void *get_item(Thing *c, int index) { return *(c->array + index); // or return c->array[index]; }
如果需要索引处的指针地址:
void **get_item_cell(Thing *c, int index) { return c->array + index; // or return &c->array[index]; }
在第二部分中,您不取消引用指针(对于+选项),或取出数组结果的地址,因为它会自动取消引用它。
编辑:我想我现在知道你想要什么。 你有一个类似于我上面第二个的function,但它是:
void *get_item_cell(Thing *c, int index) { return (void *)(c->array + index); }
您想要取消引用此函数返回的值,并访问该对象。 在这种情况下,您只能安全地使用选项4。 由于你没有索引,你不能移动到任何其他单元格(你不知道你是在数组的末尾,还是在开头 – 所以没有添加或减少)。 你只能修复上述函数的错误:cast to void **
,然后取消引用它: *(void **)item
。 这会给你一个void *
。 如果要访问从此单元格指向的对象,则还需要将其some_object_ptr *obj = *(void**)item
转换为正确的类型: some_object_ptr *obj = *(void**)item
。
你使用void*
和void**
事实并不重要,指针算法仍然可以正常工作,所以你写的两个选项都是正确的。
这是一个例子:
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; }
因为它是void*
你可以把指针指向任何东西,只是不要忘记它在使用前转换为原始类型;)
全能推!
any_type x ; void * v = * ( void * * ) & x ;
万能的拉!
void * v ; any_type x = * ( any_type * ) & v ;
小心丢失/获得数字