malloc 分配错误 - llvm ir 代码

malloc allocation error - llvm ir code

在下面的代码中,我创建了几个长度为 4 个元素的数组。但是,这很好用,当我使它们变大(5 或 6 个)元素时,出现以下错误。

IR 代码

declare [4 x double] @malloc(double)

declare double @printd(double)

define double @__anon_expr0() {
entry:
  %foo = alloca [4 x double]
  %calltmp = call [4 x double] @malloc(double 2.560000e+02)
  %0 = insertvalue [4 x double] %calltmp, double 1.000000e+00, 0
  %1 = insertvalue [4 x double] %0, double 1.000000e+00, 1
  %2 = insertvalue [4 x double] %1, double 1.000000e+00, 2
  store [4 x double] %2, [4 x double]* %foo
  %3 = getelementptr [4 x double], [4 x double]* %foo, i32 0, i32 0
  %__ = load double, double* %3
  %calltmp1 = call double @printd(double %__)
  %4 = getelementptr [4 x double], [4 x double]* %foo, i32 0, i32 0
  %__2 = load double, double* %4
  %calltmp3 = call double @printd(double %__2)
  ret double %calltmp3
}

define i32 @main() {
  call double @__anon_expr0 ()
  ret i32 0
}

错误

built(16968,0x7fff8f39c380) malloc: *** mach_vm_map(size=140732867354624) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug

导致错误的原因是什么?我认为 malloc 可以处理超过 4 个元素的数组。我在这里做错了什么?

malloc 的签名是 void* malloc(size_t size) 其中 size_t 是平台特定的整数类型(32 位在 32 位平台上,64 位在 64 位平台上).

因此,当您将其声明为采用双精度并以此方式调用它时,您将调用未定义的行为。实际上,您将值 256.0 移动到第一个参数的双精度寄存器中,然后调用 malloc,它将从第一个参数的整数寄存器中读取其参数(从未初始化)。

相反,您应该声明 malloc 在 64 位平台上采用 i64,在 32 位平台上采用 i32。然后您还应该使用整数参数调用它(即 256 而不是 2.56e2)。

另一个问题是 return 类型:malloc return 是一个指针,而不是数组(C 函数从不 return 数组——这在语法上什至是不可能的).所以应该这样声明和使用它。