为什么这段代码在 64 位架构上会出现段错误,但在 32 位架构上却可以正常工作?

发布于 2024-12-06 06:51:40 字数 311 浏览 0 评论 0原文

我遇到了以下 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

缺⑴份安定 2024-12-13 06:51:40

转换为 int* 掩盖了这样一个事实:如果没有正确的 #includemalloc 的返回类型将被假定为 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 of malloc is assumed to be int. IA-64 happens to have sizeof(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.

倾其所爱 2024-12-13 06:51:40

很可能是因为您未包含 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 from malloc 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. The void* 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).

贱贱哒 2024-12-13 06:51:40

这就是为什么在编译时永远不会出现关于缺少原型的警告。

这就是为什么你从不在 C 中强制执行 malloc 返回的原因。

强制转换是 C++ 兼容性所必需的。没有什么理由(阅读:这里没有理由)忽略它。

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

This is why you never compile without warnings about missing prototypes.

This is why you never cast the malloc return in C.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文