[英]Void pointer to struct pointer inside a structure without dereferencing it
Let's imagine I have 3 different types of datasets in 3 different structs: 让我们假设我在3种不同的结构中有3种不同类型的数据集:
typedef struct
{
int a;
//...
}DATATYPE1;
typedef struct
{
int a;
//...
}DATATYPE2;
typedef struct
{
int a;
//...
}DATATYPE3;
Then imagine I want one of those types of data to be assigned to a main struct like this: 然后想象我希望将这些类型的数据之一分配给主结构,如下所示:
typedef struct
{
int b;
void* data;
//...
}OBJECT;
Say I declare OBJECT* abc = malloc(sizeof(OBJECT));
假设我声明
OBJECT* abc = malloc(sizeof(OBJECT));
and DATATYPE1* dt1 = malloc(sizeof(DATATYPE1));
和
DATATYPE1* dt1 = malloc(sizeof(DATATYPE1));
Is there a way I could then cast in the code something like this: 有没有办法在代码中强制转换为:
abc->data = dt1;
and then call: 然后打电话:
(abc->data)->a;
without dereferencing the abc->data
pointer back to eg DATATYPE1* dp = abc->data
and then use dp->a;
没有解除引用
abc->data
指针回到eg DATATYPE1* dp = abc->data
然后使用dp->a;
I assume that the problem is that you want to access the a
field of your three DATATYPE
S, without knowing which DATATYPE
is actually present. 我假设问题是你想要访问三个
DATATYPE
S的a
字段,而不知道实际存在哪个DATATYPE
。 The answer, is yes you can, because the C specification explicitly says that whatever DATATYPE
is present, the pointer points at the first member of the structure, and hence can be safely cast to that type. 答案是肯定的,因为C规范明确指出无论
DATATYPE
存在什么,指针都指向结构的第一个成员,因此可以安全地转换为该类型。
See: Are there any guarantees about C struct order? 请参阅: 对C结构顺序有任何保证吗? and especially:
特别是:
15 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared.
15在结构对象中,非位字段成员和位字段所在的单元具有按声明顺序增加的地址。 A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa.
指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。 There may be unnamed padding within a structure object, but not at its beginning.
结构对象中可能存在未命名的填充,但不是在其开头。
Hence, the following code allows you to access a: 因此,以下代码允许您访问:
OBJECT* abc = malloc(sizeof(OBJECT));
abc->data = malloc(sizeof(DATATYPE1));
int* pointerToA = (int*) abc->data;
Whether this is good programming practice is another question, that I will not answer. 这是否是良好的编程习惯是另一个问题,我不会回答。
You need to declare everything that you will make reference in your C code. 您需要在C代码中声明要引用的所有内容。 This is the only way to the compiler knows the size and location of the object in that specific address.
这是编译器知道该特定地址中对象的大小和位置的唯一方法。
I think you can use anonymous union blocks and do something like this: 我认为你可以使用匿名联合块并做这样的事情:
typedef struct
{
int b;
union {
void* data;
DATATYPE1 *dt1;
DATATYPE2 *dt2:
DATATYPE3 *dt3;
};
} OBJECT;
then use : 然后使用:
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.