恶意分配错误 - LLVM IR 代码



在下面的代码中,我创建了几个长度为 4 个元素的数组。这工作正常,但是,当我使它们变大(5 或 6(元素时,我收到以下错误。

红外代码

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(。

另一个问题是返回类型:malloc返回指针,而不是数组(C 函数从不返回数组 - 这在语法上甚至是不可能的(。因此,应该这样声明和使用它。

最新更新