我正在尝试使用双void
指针,但我对使用情况有点困惑。
我的struct
包含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。而不是选择。 ..
有人可以告诉我这件事吗?如果我做出任何无效的假设,那么请你纠正我吗?
答案 0 :(得分:23)
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]
。
答案 1 :(得分:2)
关于指针的一个快速提示:如果你正在施法,你可能做错了。
至于你的问题。我不确定你问题中item
是什么。在您的第一部分中,您已经发现了如何访问阵列中的成员。你可以简单地使用它:
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];
}
在第二部分中,您不取消引用指针(对于+选项),或取数组结果的地址,因为它会自动取消引用它。
编辑: 我想我现在知道你想要什么。你有一个类似于我上面第二个的功能,但它是:
void *get_item_cell(Thing *c, int index)
{
return (void *)(c->array + index);
}
您想要取消引用此函数返回的值,并访问该对象。在这种情况下,您只能安全地使用选项4。由于你没有索引,你不能移动到任何其他单元格(你不知道你是在数组的末尾,还是在开头 - 所以没有添加或减少)。您只能修复上述函数的错误:强制转换为void **
,然后取消引用它:*(void **)item
。这将为您提供void *
。如果要访问从此单元格指向的对象,则还需要将其强制转换为正确的类型:some_object_ptr *obj = *(void**)item
。
答案 2 :(得分:1)
您使用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*
你可以把指针指向任何东西,只是不要忘记在使用它之前强制转换为原始类型;)
答案 3 :(得分:-3)
万能的推!
any_type x ;
void * v = * ( void * * ) & x ;
全能的拉!
void * v ;
any_type x = * ( any_type * ) & v ;
小心丢失/获得数字