c++中这个数组的静态分配和动态分配有什么区别

C++ what is the difference between static and dynamic allocation of this array?

本文关键字:动态分配 什么 区别 分配 静态 数组 c++      更新时间:2023-10-16
int length = 5;
int hi[length];

int length = 5;
int *hi = new int[length];

我被告知在C中,当你试图静态分配数组时,编译器会报错。因此,如果需要未知大小的数组,就需要动态分配内存。然而,现在有了允许第一个示例的编译器,它们究竟在做什么呢?它们还在数据段中,还是不在堆上?如果它们在堆上,那么两个例子之间的区别是什么,为什么我仍然需要在第二个例子中调用delete[],而不是在第一个例子中调用?

然而,现在有编译器允许第一个例子,他们到底在做什么?它们还在数据段中,还是不在堆上?如果它们在堆上,那么两个例子之间的区别是什么,为什么我仍然需要在第二个例子中调用delete[],而不是在第一个例子中调用?

第一个是声明一个静态变量(通常在堆栈*上),该变量将在定义的代码块的末尾结束

第二个是动态分配一个变量(通常在堆上*),这意味着你可以决定在哪里用delete[]释放它(是的,你应该记得这样做)。

在数组上下文中,两者之间的主要区别在于,第二个数组可以通过释放它所指向的内存(例如前一个数组)来轻松地调整大小,并使其指向仍然动态分配的新数组。

int* arr = new int[5];
[...]
delete[] arr;
arr = new int[10];

静态数组int hi[length]通常声明一个不应该被修改的const int*。也就是说c++提供了一整套可以/应该用来代替数组的容器。

[*] 注意:c++标准没有指定在哪里分配动态或静态内存

大概是你的代码

int length = 5;
int hi[length];

在本地作用域,而不是文件作用域,因为后者是不合法的。

它们还在数据段中吗

他们永远不会进入数据段;它们在堆栈上(在典型/常见实现中;语言标准没有说明它们去了哪里)。

为什么我仍然需要在第二个例子中调用delete[],而不是第一个例子?

首先,VLA(可变长度数组如hi[length])在c++中是不合法的,所以你不能调用delete[]。但是没有必要调用delete,因为hi在它所在的块的末尾超出了作用域。由new分配的对象或数组OTOH在删除之前不会超出作用域。只有指针hi超出了作用域,但是您可能已经将其值赋给了仍在作用域内的另一个指针。