C++ 如何删除向量中的元素。(擦除无效)

C++ 如何删除向量中的元素。(擦除无效),c++,windows,memory,vector,erase,C++,Windows,Memory,Vector,Erase,当我用“擦除”删除向量中的元素时,没有内存被清除。例如,我制作了一个大小为2000的向量。创建后,程序使用1.5 MB内存。当我执行擦除调用时,不会清除任何内容。所有的元素都消失了。但它们仍在记忆中 例如: #include <iostream> #include <vector> using namespace std; int main() { //Makes a vector of 2000 items vector<int> te

当我用“擦除”删除向量中的元素时,没有内存被清除。例如,我制作了一个大小为2000的向量。创建后,程序使用1.5 MB内存。当我执行擦除调用时,不会清除任何内容。所有的元素都消失了。但它们仍在记忆中

例如:

#include <iostream>
#include <vector>

using namespace std;


int main()
{
    //Makes a vector of 2000 items
    vector<int> test(200000);

    //Pause for test purpose
    system("pause");

    //erase all elements
    test.erase(test.begin(),test.end());

    //Pause for test purpose
    system("pause");

    return false;
}
#包括
#包括
使用名称空间std;
int main()
{
//生成2000个项目的向量
病媒测试(200000);
//暂停测试
系统(“暂停”);
//删除所有元素
test.erase(test.begin(),test.end());
//暂停测试
系统(“暂停”);
返回false;
}

大小返回0。但该过程仍使用1.5MB内存。

erase
不会释放内存。在有问题的代码之后,
测试。标准要求容量()>=200000
。使用

test.shrink_to_fit(); // in C++11
vector<int>(test).swap(test); // in C++03
test.shrink_to_fit();//在C++11中
向量(测试)。交换(测试);//在C++03中

减少向量的容量。请注意,这仍然不能保证系统其余部分看到的内存使用会下降。进程堆的大小通常不能减小。

您可以这样测试它:

int main() 
{ 
    //Makes a vector of 2000 items 
    {
        vector<int> test(200000); 

       //Pause for test purpose 
       system("pause"); 

       //erase all elements 
       test.erase(test.begin(),test.end()); 

       // Call erase or not, but destructor will be called here - freeing all memory
    } 

    //Pause for test purpose 
    system("pause"); 

    return false; 
} 
intmain()
{ 
//生成2000个项目的向量
{
病媒测试(200000);
//暂停测试
系统(“暂停”);
//删除所有元素
test.erase(test.begin(),test.end());
//不管是否调用擦除,但这里将调用析构函数-释放所有内存
} 
//暂停测试
系统(“暂停”);
返回false;
} 

vector.erase
deons不要为了简单的目的而释放内存-可能是为了重用它分配的内存,而不是为将来的请求重新分配内存。

当进程终止时,在您的情况下会回收内存。因此,不需要删除向量。
如果你想在循环中继续使用向量,那么考虑使用<代码> CULL()/<代码>来清除向量的内容。 如果在对象中使用向量,那么一旦对象被销毁,向量也会被销毁。

但是,如果向量包含指针,则必须显式删除它们。

进程保留内存的原因有两个:

  • std::vector
    只会在内存增长时重新分配内存,而不会在内存收缩时重新分配内存
  • 释放的内存通常由要重用的进程保留
在C++11中,向量有一个
shorn_to_fit
成员函数,它将要求向量尽可能减少分配的内存量。不过,不能保证它能做到这一点。在C++03中,或者如果要保证释放多余的内存,可以使用将向量与新分配的向量交换的技巧:

std::vector<int>(test).swap(test);
std::vector(测试).swap(测试);
或者,如果要完全清除它:

std::vector<int>().swap(test);
std::vector().swap(测试);
这个技巧将分配内存的所有权转移到临时向量;在表达式末尾,该向量将被销毁,从而释放内存

是否从进程中释放内存完全取决于库如何管理空闲存储。通常,小的分配(可能高达几兆字节)由堆处理——进程从系统请求大块内存,并将它们分割成小块。除非所有的小块都被释放,否则这些块就不能被释放,而许多实现甚至在那时也不会释放它们

可以直接从系统请求更大的分配,在这种情况下,一旦释放它们,就会释放它们

因此,您可以通过以下代码获得预期效果:

// A few gigabytes will probably be allocated directly.
// You'll have to reduce this on a 32-bit system, or if there's not enough memory
std::vector<int> test(1000000000)

// Use the "swap trick" to ensure the memory is deallocated.
std::vector<int>().swap(test);
//可能会直接分配几GB。
//在32位系统上,或者如果没有足够的内存,您将不得不减少此操作
标准::病媒测试(100000000)
//使用“交换技巧”确保释放内存。
std::vector().swap(测试);

但也不能保证即使这样也会释放进程中的内存;内存分配的细节不是由标准规定的,而是由编译器/库实现决定的。

如何衡量进程使用的内存?也许你应该阅读以下内容:希望有帮助。将
测试
传递到构造函数中有什么意义?为什么不直接用一个空向量交换
temp
?@sharptooth:即使你只想删除部分元素,发布的代码也会更通用。整个过程都使用向量。所以我不能在我的例子中使用这个。我想在向量活着的时候清理它。在整个过程中都会用到它。所以我不能在我的例子中使用这个。正如其他人所说的,swap()技巧或收缩_到_fit()将清理向量。内存是否被回收取决于库或编译器的实现。出于优化的原因,他们通常不会这样做。