为什么这段代码会在64位架构上发生段错误但在32位上运行良好?

时间:2011-09-25 12:03:08

标签: c pointers segmentation-fault

我遇到了以下C拼图:

问:为什么以下程序会在IA-64上发生段错误,但在IA-32上运行良好?

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

我知道64位机器上int的大小可能与指针大小不同(int可能是32位,指针可能是64位)。但我不确定这与上述计划有什么关系。 有什么想法吗?

3 个答案:

答案 0 :(得分:120)

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

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

comp.lang.c FAQ有一个条目讨论why casting the return from malloc is never needed and potentially bad

答案 1 :(得分:30)

很可能是因为你不包含 malloc的头文件,而编译器通常会警告你这一点,你明确地转发了返回值的事实意味着你告诉它你知道你在做什么。

这意味着编译器期望从int返回malloc,然后将其转换为指针。如果它们的大小不同,那将会让你感到悲伤。

这就是你从不在C中强制转换malloc的原因。它返回的void*将被隐式转换为正确类型的指针(除非你避风港)包括标题,在这种情况下它可能会警告你可能不安全的int-to-pointer转换。)

答案 2 :(得分:9)

这就是为什么你从不编译而没有关于缺少原型的警告。

  

这就是你永远不会在C中强制转换malloc的原因。

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

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