【问题标题】:Segfault on IA-64, but not on IA-32IA-64 上的段错误,但 IA-32 上没有
【发布时间】:2011-07-20 05:09:27
【问题描述】:

我无法访问我的original account。如果可能,请版主合并帐户。
这是我的问题。 以下 C 程序段错误为 IA-64,但在 IA-32 上运行良好。

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

为什么会这样?

【问题讨论】:

  • @wacko__Cracko:IA-64?真的吗?你用的是安腾?还是您的意思是 EMT64/AMD64?
  • 一个非常糟糕的面试问题。
  • 在 C 中永远不会从 malloc 转换返回值。如果这产生错误,则说明您错过了原型。
  • 这个问题是直接从gowrikumar.com/c拉出来的
  • 这是stackoverflow.com/questions/7545365/… 的精确副本,它有 58 票,虽然这是后来的问题,所以真的 it 应该是副本。

标签: c puzzle


【解决方案1】:

我能想到的原因之一是考虑到 99 之前的编译器,malloc 的原型丢失了。

不推荐使用隐式 int(返回类型)。但是,如果您的代码出现段错误,则意味着编译器假定函数(范围内没有任何原型)默认返回整数。因此,malloc 将被视为返回整数而不是指针。

在 32 位实现中,sizeof(int)sizeof(void*) 各为 32 位。在 64 位实现上,sizeof(int) 仍然相同,但 sizeof(void*) 是 64 位。

将 64 位指针截断到 32 位可能会导致该问题。

包含<stdlib.h> 以解决问题。

【讨论】:

  • 好卡。由于没有包含相关的头文件,int/void* 不匹配是一个不错的选择。
  • 仅当系统是 LLP64 或 LP64 而不是 ILP64 时。
【解决方案2】:

因为它是 IA64(斜体)而不是 x64,它可能是基本的东西,比如 malloc 不保证对齐,参见。 memalign 和早期版本的 IA64 不支持未对齐的内存访问。

【讨论】:

  • 但是 malloc 确实保证基本数据类型的对齐。
  • 如果您访问的是 4 字节整数,对齐方式不应该是 4 字节吗?
  • glibc 返回其他库没有的 8 字节对齐地址,例如 IA64 上的 HP/UX。
  • OK HP/UX 默认为 16 字节对齐,但您可以将其设置为 1 字节对齐并获取 SEGFAULT:docstore.mik.ua/manuals/hp-ux/en/B2355-60130/malloc.3C.html
【解决方案3】:

在 C 中,如果函数没有原型,则默认返回类型为 int。在 ia64 中,指针的大小比 int 大,因此它可能会出现段错误。

更新:问题基本上是为什么您应该始终对函数进行原型设计(或为此包含适当的标头)。

【讨论】:

  • 为了增加混乱,您可以将 IA64 配置为使用 ILP64,从而使用 sizeof(int) == sizeof(int*)
  • 是的,虽然我认为在大多数 Unix/Linux 系统和 64 位 Windows 下,sizeof(int*) 是 64 位,而 sizeof(int) 是 32 位。我想有更多的软件依赖于sizeof(int) == 4这个事实而不是假设sizeof(int) == sizeof(int*)的软件
猜你喜欢
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多