MS Stl库是否包含内存泄漏? 我遇到了Web(不记得在哪里)一个注释,说明MS C++的STL容器在其()中有一个内存泄漏< /COD> API。
因此,如果您有:MS Stl库是否包含内存泄漏? 我遇到了Web(不记得在哪里)一个注释,说明MS C++的STL容器在其()中有一个内存泄漏< /COD> API。,c++,memory,C++,Memory,因此,如果您有: void main() { std::vector<int> vVec; for(int i =0; i < 100; i++) vVec.push_back(i); vVec.clear(); } void main() { std::向量vVec; 对于(int i=0;i
void main()
{
std::vector<int> vVec;
for(int i =0; i < 100; i++)
vVec.push_back(i);
vVec.clear();
}
void main()
{
std::向量vVec;
对于(int i=0;i<100;i++)
vVec.推回(i);
vVec.clear();
}
因此,在堆上为向量分配的内存并没有真正释放
void main()
{
std::vector<int> vVec;
for(int i =0; i < 100; i++)
vVec.push_back(i);
vVec.clear();
vector<int>(vVec).swap(vVec);
}
便条上说(据我记忆所及)以下技术可以确保内存被真正释放
void main()
{
std::vector<int> vVec;
for(int i =0; i < 100; i++)
vVec.push_back(i);
vVec.clear();
vector<int>(vVec).swap(vVec);
}
void main()
{
std::向量vVec;
对于(int i=0;i<100;i++)
vVec.推回(i);
vVec.clear();
向量交换(vVec);
}
你有这样的经验吗?以上是真的吗?如果是,这里到底发生了什么
(最后一个问题,对不起,这是否适用于所有其他stl容器?)
谢谢,std::vector
允许分配比所需内存更多的内存(这是必要的,以便能够在摊销的固定时间内追加元素)
clear()
没有义务(事实上,不允许)释放为元素分配的内存
但是,我不会将上述行为称为内存泄漏,因为当向量超出范围时,内存将正确释放。这不是内存泄漏;这是(按标准)所要求的行为。
std::vector::clear()
不允许降低容量,因此
无法释放其缓冲区。内存将在
调用析构函数,在交换中,缓冲区将被交换,因此在
vector<int>().swap(vVec);
将首先使用精确大小的缓冲区制作(临时)副本,然后
使用vVec
交换缓冲区。结果将是vVec
具有
容量等于它的大小,不再多。(从形式上讲,这不是
该标准在任何地方都有保证,但在实践中,它对应于
(我知道的所有实现。)如果代码中有一个bug,您可能想说vector()。swap(vVec)
创建一个空的临时变量,用给定的向量交换其缓冲区,然后释放它,使vVec
没有缓冲区。但是你可能不需要这样做,clear()
的行为是一种优化,而不是一个bug(请参阅@awoodland的答案)。@Kos:再次感谢,这不是我的代码,而是我在网上注意到的一个代码片段。那么你说向量(vVec)是不需要的?我认为这是不正确的,因为它调用了临时的copy构造函数,然后将副本与原始副本交换——在我看来这是胡说八道。在第二段中,s/employed/allowed/clear()
不允许减少容量()
,因此在实践中,它无法释放内存。我删除了我的答案,支持这一点,因为它说的关键点比我想的要简洁得多。C++11还有收缩以适应,这会降低向量匹配其大小的能力,除非实现认为不值得麻烦。它还可以通过移动向量来避免复制向量的内容。这对int
没有影响,但对其他值类型可能会有影响。@SteveJessop如果确实改变了容量,如何收缩以适应
避免移动它们?使用::operator new
,默认分配器是(以前是?)必需的,并且在new/delete
界面中没有更改已分配块大小(并仅释放部分块)的规定。@James:它不会避免移动块,但可以避免复制块<代码>向量(vVec).swap(vVec)代码>无法避免复制它们(至少,如果复制构造函数具有可观察的效果,则不会)。