访问结构和空指针

Accessing structs and void pointers

我读到可以从任何指针隐式转换为 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*

a->arr; 等同于 (*a).arr;a 属于 void * 类型,无法取消引用。在取消引用之前,您需要将 a 转换为 FOO *

((FOO *)a)->arr;

您可以将任何指针类型分配给 void *,但如果您想取消引用它,则需要将其强制转换。否则,无法知道结构。 A void 没有 structure/members 并且没有机制假设 void *.

指向的内存可能的有效类型

考虑你的例子稍作改动会更清楚

#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;
}

你能说出对象指针 a 指的是什么吗?:)

类型 void 是不完整的类型。您可能会注意到定义类型为 void 的对象。但是这个表达式

a->arr;

看起来像 "access data member arr of an object of type void".:)

为了让上面的程序能够编译,你必须写一些类似

的东西
if ( x % 2 == 0 ) ( ( FOO1 * )a )->arr = NULL;
else ( ( FOO2 * )a )->arr = NULL;

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