我研究了 STL 向量的实现。矢量容器被实现为动态数组。clear() 方法用于销毁向量中的所有元素,它将向量的大小设置为 0,但容量保持不变。所以,如果我理解正确,所有元素都被称为它们的析构函数,但动态分配的内存仍然可用。为了仍然释放它,我们可以这样做:
Vec.swap( vector<T>() ); // Capacity = 0.
但是让我们假设我们没有使用交换,只是明确了。内部实现(如果我错了,请纠正我)大约等于以下内容(以非常简化的方式):
// A contained type:
struct C {
int m;
C() : m(123){}
};
C * arr = new C[10]; // Suppose this is the internal array in the container
编辑:我知道上面的 new 运算符没有在实际实现中使用,并且 STL 使用分配器,我只是使用 new 作为测试用例来测试析构函数(这只是一个类比)。
// Calling clear() :
for(size_t i=0;i<SZ;i++)
arr[i].~C(); // Destroying ALL elements
// some other actions . . .
但是现在容量还是10,内存还有一些我们可以访问的数据:
// Accessing the vector at 0:
cout<<arr[0].m<<endl; // This prints 123
这是未定义的行为吗?好吧,似乎是这样,但我想确定。
也许如果我更深入地了解调用析构函数时会发生什么(关于堆栈内存),我可以肯定地知道,这是否等于程序超出函数范围时调用析构函数,或者调用析构函数在退出范围之前被认为就像任何方法一样,并且对象的堆栈内存没有被释放?
免责声明:上面的代码非常简化,以象征 clear() 的部分功能,以及我从研究中得出的结论,如果我错了,您可以纠正我。