vector::clear() 幕后与破坏
vector::clear() behind the scenes & destruction
我研究了STL vector的实现。Vector容器实现为动态数组。clear()方法用于销毁vector中的所有元素,它将vector的大小设置为0,但容量保持不变。所以,如果我理解正确的话,所有的元素都被称为它们的析构函数,但是动态分配的内存仍然可用。为了仍然释放它,我们可以这样做:
Vec.swap( vector<T>() ); // Capacity = 0.
但是假设我们没有使用swap,只做了一个clear。内部实现(如果我错了请纠正我)大致等于以下内容(以非常简化的方式):
// 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使用allocator,我只是使用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()所做的一部分,这是我从我的研究中得出的结论,如果我错了,你可以纠正我。
std::vector<...>::clear()
只是销毁对象并适当地设置其内部记录以表明没有对象,这是正确的。当访问被销毁的对象时,你会有未定义的行为:尽管数据中的位可能没有改变,但相关的对象也可能被销毁,并且它们的内存可能被回收用于其他目的。
在你的例子中,C
只是存储一个int
,并没有在析构函数中对它做任何事情,比特可能是不变的,但没有保证。特别是调试实现可能会浪费几个周期,故意将垃圾写入销毁对象的内存中。
只是一个旁注:std::vector<...>
不会使用new C[n]
,而是通过分配器分配和释放原始内存。但是,这是一个细节。
如果我理解正确的话,你的主要问题是:
这是未定义的行为吗?
对于一个常规数组,是的,你有一个未定义的行为,原因在前面的答案中解释过。但是,如果试图用索引等于或大于大小(注意,不能超过容量)的std::vector
的元素访问,则访问操作符将抛出std::out_of_range
异常(尽管函数clear()
确实调用了vector的每个元素的析构函数,并且不改变其容量,但它确实改变了vector包含多少元素的内部计数)。
您的程序使用的内存区域:堆栈和堆。你把arr向量地址放在堆内存中,但是m的值驻留在堆栈中。如果要删除堆内存,请使用delete [] arr,如果要删除未寻址内存,请使用
arr = NULL你的结构可以很容易地像这样修改
struct C {
int *m;
C(int value) {
m=new int(value);
}
~C()
{
delete m;
}
};
- 如果 std::vector::clear() 不是静态的,如何在没有实例的情况下调用它?
- 了解 cin.fail() 和 cin.clear语言 - Vector 追加程序
- std::vector::clear()ing 二维向量线程的内部向量安全吗?
- 在从 std::vector 移动的上调用 .clear()、.shrink_to_fit()、.empty() 是否合
- 为什么 vector.clear() 在循环中不起作用?
- 为什么 vector::clear 在 foreach 循环中不起作用
- std::vector中的clear()是否会产生内存泄漏
- 如何在vector::clear()上保持向量元素的容量
- VS2010: assert "vector iterators incompatible" in std::vector.clear()
- 我是否应始终在功能末尾调用vector clear()
- vector clear()似乎无法释放push_back中分配的内存
- 在使用运算符=进行赋值之前,需要调用std::vector.clear()
- std::vector<std::p air<const int, const int> >::clear() VS 2010 no-compile
- visual C++ - 调用 std::vector 的 .clear() 时访问违规
- Visual Studio 2010, C++, "vector iterators Incompatible" 在 vector.clear() 期间
- 更有效的是:vector.clear()或if(vector.empty())clear();
- 为什么 vector::clear 不从向量中删除元素?
- 为什么这段代码工作正常?(vector.clear(), vector<vector<int> >)
- 在 std::vector::clear 之后对矢量中的构造/破坏感到困惑
- C++ std::vector::clear() crash