我读到void指针可以从任何指针隐式转换,但看起来它们不能用于结构,我做了一个例子:
typedef struct FOO{
int *arr;
size_t size;
} FOO;
int main()
{
void * a;
FOO * b = (FOO*)malloc(sizeof(FOO));
a = b;
b->arr;//works, accessed arr
a->arr;//error: expression must have pointer-to-struct-or-union type
}
我可以看到a
和b
具有相同的地址,但我无法使用a
,就好像它与b
的类型相同,为什么是什么?
另一个相关的问题是,绝对可以将任何指针隐式地转换为void *
吗?甚至可以FOO****
到void*
?
答案 0 :(得分:1)
a->arr;
相当于(*a).arr;
。 a
属于void *
类型,无法取消引用。在解除引用之前,您需要将a
转换为FOO *
。
((FOO *)a)->arr;
答案 1 :(得分:1)
您可以将任何指针类型指定给void *
,但如果要取消引用它,则需要将其转换回来。否则,结构不可知。 void
没有结构/成员,并且没有机制为void *
指向的内存假设可能的有效类型。
答案 2 :(得分:1)
如果您的示例有微小变化,那就更清楚了
#include <stdlib.h>
#include <time.h>
typedef struct FOO1{
int *arr;
size_t size;
} FOO1;
typedef struct FOO2{
int *arr;
size_t size;
} FOO2;
int main()
{
void * a;
srand( ( unsigned int )time( NULL ) );
int x = rand();
if ( x % 2 == 0 )
{
a = malloc( sizeof( FOO1 ) );
}
else
{
a = malloc( sizeof( FOO2 ) );
}
a->arr;
}
你能说出一个对象指针指的是什么?:)
类型void
是不完整的类型。您可能会注意到定义void类型的对象。但是这个表达
a->arr;
看起来像“访问类型为void的对象的数据成员arr。”。)
所以上面的程序会编译你必须编写像
这样的东西if ( x % 2 == 0 ) ( ( FOO1 * )a )->arr = NULL;
else ( ( FOO2 * )a )->arr = NULL;
那就是你需要将指针强制转换为你要访问的对象的类型。