clear()
成员函数来“重置”向量,假设它不仅会清除元素中的项目并重置大小数据成员,而且它还会使堆返回内存。以前与它一起使用。好吧,我偶然发现了一个关于向量的帖子,说这不是从Vector中获取内存的正确方法,因为使用clear()
不会这样做,但是需要使用swap方法:
vector<MyClass>().swap(myVector);
我很好奇为什么我们必须调用交换来删除旧内存?我认为这更像是一种解决方法,因为我们正在使用交换,但还有其他事情正在发生。一个析构函数被调用了吗?
最后一个问题,我现在读到的所有文章都说clear()
没有解除对象被“破坏”的记忆。任何人都可以澄清这是什么意思吗?我不熟悉白话。我假设如果一个对象被销毁,它被清除掉并且内存被送回堆中,但这是错误的,“destroy”这个词是指擦除与每个元素相关的位吗?我不确定。任何帮助将不胜感激。感谢。
答案 0 :(得分:3)
要回答这个问题,您需要将vector
直接分配的内存与通过成员对象间接“拥有”的内存分开。例如,假设MyClass
是一个占用1000个字节的对象,然后使用std::vector<std::unique_ptr<MyClass>>
。然后,如果该向量具有10个元素,则直接分配的内存通常在64位系统上接近10 * 8 = 80字节,而unique_ptr
对象间接拥有10 * 1000 = 10000字节。
现在,如果在向量上调用clear()
,则会在每个unique_ptr
元素上调用析构函数,因此将释放10000个间接拥有的字节。但是,基础数组存储未被释放,因此仍然会分配向量直接拥有的80多个字节。 (此时,向量的capacity()
至少为10,但size()
为0.)如果随后调用向量的析构函数,则会导致存储数组也被释放。
现在,如果你执行
std::vector<std::unique_ptr<MyClass>>().swap(v);
让我们分解它的作用:首先,创建一个临时矢量对象,它没有已分配的数组,而capacity()
为0.现在,swap
传递{{1}的基础数组临时向量,并将空数组或空数组从临时向量交换为v
。最后,在表达式的末尾,临时对象超出范围,因此调用其析构函数。这会导致先前属于v
的任何元素的析构函数被调用,然后释放以前属于v
的基础数组存储。所以在这结束时,v
为0,并且以前属于v.capacity()
的所有内存都被释放,无论它是由v
直接分配还是通过存储的{{间接属于它}。 1}}对象。
答案 1 :(得分:2)
vector
有一个名为capacity
的关联数量,这意味着它已为这么多元素分配了足够的内存,即使它实际上实际上并不包含那么多元素。
如果在不超出容量的情况下在向量中添加或删除元素,则不会分配或释放内存;个人元素&#39;构造函数和析构函数在已经分配的空间上运行。
clear()
功能无法更改容量。但是,vector::swap()
的通常实现也会交换向量的容量;因此,使用空向量进行交换将导致原始向量具有默认容量,该容量将很小甚至为零(取决于实现),因此应释放内存。
从C ++ 11开始,有一种减少容量的正式方法,称为shrink_to_fit()。
请注意,C ++标准实际上并不要求在减少容量后将内存释放到操作系统;它取决于您使用的库实现的作者和操作系统的组合。