我遇到了以下C拼图:
问:为什么以下程序会在IA-64上发生段错误,但在IA-32上运行良好?
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
我知道64位机器上int
的大小可能与指针大小不同(int
可能是32位,指针可能是64位)。但我不确定这与上述计划有什么关系。
有什么想法吗?
答案 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 ++兼容性,并且在少数情况下根本不可能,但在大多数情况下,它很容易实现。