【问题标题】:How to delete elements in a vector. (erase won't work )如何删除向量中的元素。 (擦除不起作用)
【发布时间】:2012-03-06 13:46:07
【问题描述】:

当我使用“擦除”删除向量中的元素时,不会清除内存。例如,我制作了一个大小为 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;
}

Size 返回 0。但该进程仍使用 1.5MB 内存。

【问题讨论】:

标签: c++ windows memory vector erase


【解决方案1】:

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

  • std::vector 只会在内存增长时重新分配内存,而不是在缩小时。
  • 释放的内存通常由要重用的进程保留。

在 C++11 中,向量有一个 shrink_to_fit 成员函数,它会要求向量尽可能减少分配的内存量。但是,不能保证它会这样做。在 C++03 中,或者如果您想保证释放多余的内存,您可以使用将向量与新分配的向量交换的技巧:

std::vector<int>(test).swap(test);

或者如果你想彻底清除它:

std::vector<int>().swap(test);

这个技巧将分配内存的所有权转移到一个临时向量;在表达式结束时,该向量被销毁,释放内存。

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

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

所以你可以用这样的代码得到你期望的效果:

// 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);

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

【讨论】:

    【解决方案2】:

    当进程终止时,在您的情况下会回收内存。因此,无需擦除矢量。
    如果您想在循环中继续使用向量,请考虑使用clear(),它会清除向量的内容。
    如果向量被用在一个对象中,那么一旦对象被销毁,那么向量也会被销毁。
    但是,如果向量包含指针,则必须显式删除它们。

    【讨论】:

    • 我想在它还活着的时候清理它。它用于整个过程。所以我不能在我的情况下使用它。
    • 正如其他人所说的 swap() 技巧或 shrink_to_fit() 将清理向量。内存是否被回收取决于库或编译器的实现。出于优化原因,他们通常不这样做。
    【解决方案3】:

    你可能想这样测试它:

    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; 
    } 
    

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

    【讨论】:

    • 整个过程都用到了vector。所以我不能在我的情况下使用它。
    【解决方案4】:

    erase 不会释放内存。在有问题的代码之后test.capacity() &gt;= 200000 是标准要求的。使用

    test.shrink_to_fit(); // in C++11
    vector<int>(test).swap(test); // in C++03
    

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

    【讨论】:

    • test 传递给构造函数有什么意义?为什么不直接用空向量交换 temp
    • @sharptooth:发布的代码更通用 - 即使您只想删除 一些 元素也可以使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    相关资源
    最近更新 更多