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

时间:2013-03-27 03:36:35

标签: c++ c variable-length-array

int length = 5;
int hi[length];

VS

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

每当你尝试静态分配大小不是常数的数组时,我就会教C编译器在C语言中抱怨。因此,如果您需要未知大小的数组,则需要动态分配内存。但是,现在有了编译器允许第一个例子,他们究竟在做什么?它们是否还在数据段中,还是不在堆上?如果它们正在堆上,那么这些示例之间有什么区别,为什么我仍然需要在第二个例子中调用delete [],而不是第一个例子?

2 个答案:

答案 0 :(得分:2)

  

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

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

第二个是动态分配一个变量(通常在堆上*),这意味着你可以决定用delete[]解除分配的位置(是的,你应该记得这样做)。 / p>

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

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

静态数组int hi[length]通常声明const int*,不应修改它。这就是说C ++提供了一套完整的容器,可以/应该使用它们而不是数组。

[*] 注意:C ++标准没有指定动态或静态内存的分配位置。

答案 1 :(得分:0)

大概是你的代码

int length = 5;
int hi[length];

属于本地范围,而非文件范围,因为后者不合法。

  

他们是否还在进入数据段

他们从未进入数据领域;它们在堆栈中(在典型/常见的实现中;语言标准不能说它们去哪里)。

  

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

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