我知道以下情况的区别:
case 1: int a[10];
对于情况 1,数组的内存是在堆栈上分配的。
case 2: int *a = new int[10];
对于情况 2,在堆上分配内存并返回一个指针。
但是下面两个声明有什么区别,因为向量内存总是在堆上分配
vector<int> v1;
vector<int> *v2 = new vector<int>();
我知道以下情况的区别:
case 1: int a[10];
对于情况 1,数组的内存是在堆栈上分配的。
case 2: int *a = new int[10];
对于情况 2,在堆上分配内存并返回一个指针。
但是下面两个声明有什么区别,因为向量内存总是在堆上分配
vector<int> v1;
vector<int> *v2 = new vector<int>();
以下两个语句创建了一个,vector<>
但是两者之间存在一些差异。
vector<int> v1;
vector<int> *v2 = new vector<int>();
首先,实际的向量数据存储将从堆或指定内存分配器使用的任何源中分配(请参阅std::vector 分配其内存的位置?),这对两者都是相同的。
这两个区别是 (1)vector<>
管理数据的存储位置和 {2}vector<>
及其分配内存的生命周期。
在第一种情况下,vector<>
管理数据存储在本地内存,堆栈上,当vector<>
变量超出范围时,调用析构函数以消除堆上的向量数据存储空间和堆栈上的向量管理空间。在第一种情况下,当vector<>
变量超出范围时,vector<>
内存被正确释放。
在第二种情况下,vector<>
存储数据空间和vector<>
管理空间都在堆上。
因此,当包含地址的指针变量vector<>
超出范围时,vector<>
不会调用自身的析构函数。结果是内存无法恢复,因为将清理和释放为数据存储区域vector<>
和管理存储区域分配的内存的析构函数从未被调用。
第二种情况确保vector<>
正确清理的一种可能性是使用智能指针,当它超出范围时也会触发所指向事物的析构函数。
在大多数情况下,很少需要使用第二种情况new
来创建vector<>
,第一种情况不仅最常见而且更安全。
只有std::vector
存储内存被分配在堆上,其余的(即一些指向存储的指针+一些额外的数据成员)通常可以位于堆栈上,但是通过写入new vector<int>()
你强制整个事情到堆上。
通常不需要以这种方式分配向量。