在C ++中,向量的静态分配和动态分配有什么区别?

时间:2019-01-24 18:21:35

标签: c++ dynamic-memory-allocation stdvector static-memory-allocation

我知道以下情况的区别:

case 1: int a[10];

对于情况1,用于数组的内存是在堆栈上分配的。

case 2: int *a = new int[10];

对于情况2,在堆上分配内存,并返回一个指针。

但是下面两个声明之间有什么区别, 因为向量内存总是分配在堆上

vector<int> v1;
vector<int> *v2 = new vector<int>();

2 个答案:

答案 0 :(得分:4)

在堆上仅分配了std::vector存储内存,其余部分(即指向存储的指针+一些额外的数据成员)通常可以位于堆栈上,但是通过写new vector<int>()将整个东西强加到堆上。
通常不需要这种方式分配向量。

答案 1 :(得分:4)

以下两个语句创建一个vector<>,但是两者之间有一些区别。

vector<int> v1;
vector<int> *v2 = new vector<int>();

首先,实际的矢量数据存储将从堆或指定的内存分配器使用的任何源中分配(请参见Where does a std::vector allocate its memory?),并且两者都是相同的。

两个区别是(1)存储vector<>管理数据的地方和{2} vector<>及其分配的内存的生存期。

在第一种情况下,vector<>管理数据存储在本地存储器,堆栈上,并且当vector<>变量超出范围时,调用析构函数以消除向量上的矢量数据存储空间堆和堆栈上的向量管理空间。在第一种情况下,vector<>变量超出范围时,vector<>内存被正确释放。

在第二种情况下,vector<>存储数据空间和vector<>管理空间都在堆上。

因此,当包含vector<>地址的指针变量超出范围时,不会调用vector<>本身的析构函数。结果是无法恢复的内存,因为将永远不会调用将vector<>的数据存储区和管理存储区都清除并释放分配的内存的析构函数。

在第二种情况下,确保正确清理vector<>的一种可能性是使用智能指针,当该指针超出范围时,它还会触发所指向对象的析构函数。

在大多数情况下,使用new创建vector<>的第二种情况很少见,第一种情况不仅最常见,而且更安全。