访问结构和void指针

时间:2015-04-06 14:27:58

标签: c pointers syntax struct

我读到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
}

我可以看到ab具有相同的地址,但我无法使用a,就好像它与b的类型相同,为什么是什么?

另一个相关的问题是,绝对可以将任何指针隐式地转换为void *吗?甚至可以FOO****void*

3 个答案:

答案 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;

那就是你需要将指针强制转换为你要访问的对象的类型。