为什么这段代码在 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 位) 。但我不确定这与上述程序有何关系。 有什么想法吗?
I came across the following C puzzle:
Q: Why does the following program segfault on IA-64, but work fine on IA-32?
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
I know that the size of int
on a 64 bit machine may not be the same as the size of a pointer (int
could be 32 bits and pointer could be 64 bits). But I am not sure how this relates to the above program.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
转换为
int*
掩盖了这样一个事实:如果没有正确的#include
,malloc
的返回类型将被假定为int. IA-64 恰好有 sizeof(int)
sizeof(int)
sizeof(int)
sizeof(int)
sizeof(int*)
这使得这个问题变得显而易见。(另请注意,由于未定义的行为,即使在 sizeof(int)==sizeof(int*) 为 true 的平台上,它仍然可能会失败,例如,如果调用约定使用不同的寄存器来返回指针而不是整数)
comp.lang.c FAQ 有一个条目讨论 为什么从
malloc
转换返回值从来不需要,而且可能很糟糕< /a>.The cast to
int*
masks the fact that without the proper#include
the return type ofmalloc
is assumed to beint
. IA-64 happens to havesizeof(int) < sizeof(int*)
which makes this problem obvious.(Note also that because of the undefined behaviour it could still fail even on a platform where
sizeof(int)==sizeof(int*)
holds true, for example if the calling convention used different registers for returning pointers than integers)The comp.lang.c FAQ has an entry discussing why casting the return from
malloc
is never needed and potentially bad.很可能是因为您未包含
malloc
的头文件,并且虽然编译器通常会警告您这一点,但事实上您正在显式转换返回值意味着你告诉它你知道你在做什么。这意味着编译器期望从
malloc
返回一个int
,然后将其转换为指针。如果它们的尺寸不同,那会让你感到悲伤。这就是为什么您从不在 C 中强制转换
malloc
返回值。它返回的void*
将隐式转换为正确类型的指针(除非您没有包含标头,在这种情况下,它可能会警告您潜在不安全的 int 到指针转换)。Most likely because you're not including the header file for
malloc
and, while the compiler would normally warn you of this, the fact that you're explicitly casting the return value means you're telling it you know what you're doing.That means the compiler expects an
int
to be returned frommalloc
which it then casts to a pointer. If they're different sizes, that's going to cause you grief.This is why you never cast the
malloc
return in C. Thevoid*
that it returns will be implicitly converted to a pointer of the correct type (unless you haven't included the header in which case it probably would have warned you of the potentially unsafe int-to-pointer conversion).这就是为什么在编译时永远不会出现关于缺少原型的警告。
强制转换是 C++ 兼容性所必需的。没有什么理由(阅读:这里没有理由)忽略它。
C++ 兼容性并不总是需要的,在少数情况下根本不可能,但在大多数情况下它很容易实现。
This is why you never compile without warnings about missing prototypes.
The cast is needed for C++ compatibility. There is little reason (read: no reason here) to omit it.
C++ compatibility is not always needed, and in a few cases not possible at all, but in most cases it is very easily achieved.