为什么这个代码在64位元上分段,但在32位上却能正常工作?

我遇到了下面这个 C 字谜:

问: 为什么下面的程序在 IA-64上出错,但在 IA-32上运行良好?

  int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}

我知道在64位机器上 int的大小可能和指针的大小不一样(int可以是32位,指针可以是64位)。但我不确定这与上述程序有什么关系。 有什么想法吗?

17130 次浏览

最有可能的原因是因为您是 不包括malloc的头文件,虽然编译器通常会警告您这一点,但是您显式地强制转换返回值这一事实意味着您告诉它您知道自己在做什么。

这意味着编译器期望从 malloc返回 int,然后将其强制转换为指针。如果尺寸不同,你会很伤心的。

这就是为什么 永远不会在 C 中强制执行 malloc返回。它返回的 void*将隐式地转换为正确类型的指针(除非您没有包含头部,否则它可能会警告您存在潜在的不安全的 int 到指针转换)。

int*的强制转换掩盖了这样一个事实,即如果没有适当的 #include,则假定 malloc的返回类型为 int。IA-64碰巧有 sizeof(int) < sizeof(int*),这使得这个问题显而易见。

(另请注意,由于未定义的行为,即使在 sizeof(int)==sizeof(int*)为 true 的平台上,它仍然可能失败,例如,如果调用约定使用不同的寄存器来返回指针而不是整数)

常见问题解答有一个讨论 为什么从 malloc投掷回报是从来没有需要和潜在的坏的条目。

这就是为什么在没有关于丢失原型的警告的情况下绝不进行编译。

这就是为什么在 C 语言中从来不使用 malloc return 的原因。

C + + 兼容性需要强制转换。没有理由(请阅读: 这里没有理由)忽略它。

C + + 兼容性并不总是需要的,在少数情况下根本不可能,但在大多数情况下它是非常容易实现的。