这个C演员出了什么问题

时间:2010-01-18 19:10:36

标签: c casting

我昨天在一个IRC频道遇到过这个,并且不明白为什么这是不好的行为:

#include <stdio.h>

int main(void)
{
     char x[sizeof(int)] = { '\0' }; int *y = (int *) x;
     printf("%d\n", *y);
}

是否有任何数据丢失或任何损失?谁能给我任何文件来进一步解释它做错了什么?

4 个答案:

答案 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为了简单起见)。