Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compiler construction LLVM malloc和内存引用_Compiler Construction_Llvm - Fatal编程技术网

Compiler construction LLVM malloc和内存引用

Compiler construction LLVM malloc和内存引用,compiler-construction,llvm,Compiler Construction,Llvm,我正在用类似于LLVM的Java语言编写编译器。然而,我在分配内存和引用内存时遇到了一些困难。 这是我试图编译的代码: class Node { Node a; } int main () { Node n = new Node; n.a = new Node; return 0; } 我生成LLVM代码(抱歉,不能再短了): %struct.Node中的i32、i32*用于将来保存一些内部信息 declare i8* @malloc(i32) %struct.Node =

我正在用类似于LLVM的Java语言编写编译器。然而,我在分配内存和引用内存时遇到了一些困难。 这是我试图编译的代码:

class Node {
  Node a;
}

int main () {
  Node n = new Node;
  n.a = new Node;
  return 0;
}
我生成LLVM代码(抱歉,不能再短了):

%struct.Node中的i32、i32*用于将来保存一些内部信息

declare i8* @malloc(i32)

%struct.Node = type { i32, i32* , %struct.Node*}
define i32 @main()
{

    %temp_0 = call i8* @malloc(i32 12)
    %temp_1 = bitcast i8* %temp_0 to %struct.Node*
    call void @Node_init(%struct.Node* %temp_1)
    %var_0 = alloca %struct.Node*
    store %struct.Node* %temp_1, %struct.Node** %var_0

    %temp_3= load %struct.Node** %var_0
    %temp_4 = getelementptr inbounds %struct.Node* %temp_3, i32 0, i32 2

    %temp_6 = call i8* @malloc(i32 12)
    %temp_7 = bitcast i8* %temp_6 to %struct.Node*
    call void @Node_init(%struct.Node* %temp_7)
     store %struct.Node* %temp_7, %struct.Node** %temp_4
     ret i32 0
}
define void @Node_init(%struct.Node* %temp_0)
{
     %var_0 = alloca %struct.Node*
     %temp_10 = getelementptr inbounds %struct.Node* %temp_0, i32 0 
    store %struct.Node*  %temp_10, %struct.Node**  %var_0

    %temp_11= load %struct.Node** %var_0
    %temp_12 = getelementptr inbounds %struct.Node* %temp_11, i32 0, i32 2
     store %struct.Node* null, %struct.Node** %temp_12

     ret void
}
在执行过程中,valgrind显示错误:

==3217== Invalid write of size 4
==3217==    at 0x5A8901F: ???
==3217==  Address 0x570dff8 is 4 bytes after a block of size 12 alloc'd
==3217==    at 0x402BB7A: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3217==    by 0x5A8901E: ???
这很奇怪,因为当我删除其中一行时:

 call void @Node_init(%struct.Node* %temp_7)
 store %struct.Node* %temp_7, %struct.Node** %temp_4
这个问题消失了。也可以用替换的

class Node {
  Node a;
}


在对象字段上执行类似的操作不会导致任何错误。

看起来目标上的指针大小是8字节,而您假设它只有4字节。因此
getelementptr%temp,0,2
返回了指针的位置+12,而不是位置+8

换句话说,将mallocs更改为分配20个字节,而不是12个字节,它应该可以工作


通常,在生成IR时,请确保正确设置目标数据,然后使用
DataLayout
类检索指针大小。

如果指针大小为8,malloc还需要一个
i64
参数,而不是
i32
(因为通常
sizeof(size\t)==sizeof(void*)
),是吗?@sepp2k这是有道理的,但据我所知,C标准并不要求这样做,所以
size\u t
可能确实是32位的,而指针是64位的。
class Node {
  int a;
}