我昨天在一个IRC频道遇到过这个,并且不明白为什么这是不好的行为:
#include <stdio.h>
int main(void)
{
char x[sizeof(int)] = { '\0' }; int *y = (int *) x;
printf("%d\n", *y);
}
是否有任何数据丢失或任何损失?谁能给我任何文件来进一步解释它做错了什么?
答案 0 :(得分:10)
数组x
可能无法在内存中正确对齐int
。在x86上你不会注意到,但在其他体系结构上,例如SPARC,解除引用y
将触发总线错误(SIGBUS)并使程序崩溃。
任何地址都可能出现此问题:
int main(void)
{
short a = 1;
char b = 2;
/* y not aligned */
int* y = (int *)(&b);
printf("%d\n", *y); /* SIGBUS */
}
答案 1 :(得分:7)
首先,不保证数组x
能够正确对齐int
。
有一个关于这可能会影响展示位置new
等技术的对话话题。应该注意的是,在正确对齐的内存中也需要放置新的内容,但是新的贴片通常与动态分配的内存一起使用,并且需要分配函数(在C和C ++中)来返回适合任何类型的内存所以可以将地址分配给任何类型的指针。
编译器为自动变量分配的内存也是如此。
答案 2 :(得分:0)
为什么不使用联盟?
union xy {
int y;
char x[sizeof(int)];
};
union xy xyvar = { .x = { 0 } };
...
printf("%d\n", xyvar.y);
我还没有验证过,但我认为其他人提到的对齐问题在这里不会有问题。如果有人争论为什么这不便携,我想听听。
答案 3 :(得分:0)
我认为虽然对齐问题属实,但并不是全部。 即使对齐不是问题,你仍然在堆栈上占用4个字节,其中只有一个初始化为零,并将它们视为整数。 这意味着打印值有24个未初始化的位。 使用未初始化的值是一个基本的“错误”。
(假设sizeof(int)== 4为了简单起见)。