在另一个question的上下文中,讨论了是否允许(即将会或不会引入实现定义或未定义的行为)将int**
投射到void**
以及随后为解除引用的void*
分配值。这让我想到了C11 standard
6.2.5(28)指向void的指针应具有与指向字符类型的指针相同的表示和对齐要求。 ...
6.3.2.3(1)指向void的指针可以转换为指向任何对象类型的指针。指向任何对象类型的指针可以转换为指向void的指针,然后再返回;结果应该等于原始指针 6.3.2.3(7)...当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。 ...
我的问题是这是否
int* intptr = NULL;
void* dvoidptr = &intptr; /* 6.3.2.3 (1) */
*(void**)dvoidptr = malloc(sizeof *intptr); /* using 6.3.2.3 (1) */
是否符合标准?这对我来说似乎很奇怪,但我找不到一个确凿的论据,为什么不呢。 void*
到void**
由6.3.2.3和6.2.5以及6.3.2.3帮助进行对齐保证。
答案 0 :(得分:4)
代码无效。
看重点:
6.3.2.3(1)指向void的指针可以转换为指向任何对象类型的指针。指向任何对象类型的指针可能会转换为指向void 并再返回的指针;结果应该等于原始指针。
您正在将int**
转换为void*
(罚款),然后转换为其他类型void**
(不行)。 C不保证您可以安全地将void*
转换为原始类型以外的任何内容(除了转换为char *
)
此外,*(void**)dvoidptr
会产生void*
,而实际上只有int*
。例如,sizeof(void*) == 2
和sizeof(int*) == 1
怎么办?您可以将 void*
指针转换为其他类型,但不能直接将其重新解释为其他类型。