访问结构和空指针
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
}
我可以看到 a
和 b
具有相同的地址,但我不能使用 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;
那就是您需要将指针转换为您要访问的对象的类型。
我读到可以从任何指针隐式转换为 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*
?
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;
那就是您需要将指针转换为您要访问的对象的类型。