[英]Void pointer to struct pointer inside a structure without dereferencing it
让我们假设我在3种不同的结构中有3种不同类型的数据集:
typedef struct
{
int a;
//...
}DATATYPE1;
typedef struct
{
int a;
//...
}DATATYPE2;
typedef struct
{
int a;
//...
}DATATYPE3;
然后想象我希望将这些类型的数据之一分配给主结构,如下所示:
typedef struct
{
int b;
void* data;
//...
}OBJECT;
假设我声明OBJECT* abc = malloc(sizeof(OBJECT));
和DATATYPE1* dt1 = malloc(sizeof(DATATYPE1));
有没有办法在代码中强制转换为:
abc->data = dt1;
然后打电话:
(abc->data)->a;
没有解除引用abc->data
指针回到eg DATATYPE1* dp = abc->data
然后使用dp->a;
我假设问题是你想要访问三个DATATYPE
S的a
字段,而不知道实际存在哪个DATATYPE
。 答案是肯定的,因为C规范明确指出无论DATATYPE
存在什么,指针都指向结构的第一个成员,因此可以安全地转换为该类型。
请参阅: 对C结构顺序有任何保证吗? 特别是:
15在结构对象中,非位字段成员和位字段所在的单元具有按声明顺序增加的地址。 指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。 结构对象中可能存在未命名的填充,但不是在其开头。
因此,以下代码允许您访问:
OBJECT* abc = malloc(sizeof(OBJECT));
abc->data = malloc(sizeof(DATATYPE1));
int* pointerToA = (int*) abc->data;
这是否是良好的编程习惯是另一个问题,我不会回答。
您需要在C代码中声明要引用的所有内容。 这是编译器知道该特定地址中对象的大小和位置的唯一方法。
我认为你可以使用匿名联合块并做这样的事情:
typedef struct
{
int b;
union {
void* data;
DATATYPE1 *dt1;
DATATYPE2 *dt2:
DATATYPE3 *dt3;
};
} OBJECT;
然后使用:
OBJECT* abc = (OBJECT*)malloc(sizeof(OBJECT));
DATATYPE1* dt1 = (DATATYPE1*)malloc(sizeof(DATATYPE1));
abc->data = (void *)dt1;
int val = abc->dt1->a;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.