2012-02-15 57 views
2

当我用“擦除”删除矢量中的元素时,则没有清除内存。例如,我制作了一个尺寸为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; 
} 

尺寸返回0。但是,这一过程仍然使用的存储器1,5MB。

+2

你如何测量进程正在使用的内存? – 2012-02-15 07:52:27

+0

也许你应该阅读: http://stackoverflow.com/questions/586634/shrinking-a-vector 希望它能帮助。 – 2012-02-15 07:54:40

回答

8

erase不释放内存。标准要求代码test.capacity() >= 200000之后。使用

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

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

+0

将'test'传递给构造函数有什么意义?为什么不只是用空载体交换'temp'? – sharptooth 2012-02-15 07:56:40

+0

@sharptooth:发布的代码更通用 - 即使您只想删除某些元素,也可以工作。 – ybungalobill 2012-02-15 07:58:05

0

你可能喜欢这种方式测试:

简单的目的
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't释放内存 - 可能分配给它的,而不是重新分配用于将来的请求的内存可重用性。

+0

矢量用于整个过程。所以我不能在我的情况下使用这个。 – Laurence 2012-02-15 08:05:58

0

当进程终止时,内存回收你的情况。所以,不需要擦除矢量。
如果要继续在循环中使用该向量,请考虑使用清除向量内容的clear()
如果矢量用在一个对象中,那么一旦对象被销毁,矢量也被销毁。
但是,如果向量包含指针,那么你必须明确地删除它们。

+0

我想在活着时清理矢量。它在整个过程中使用。所以我不能在我的情况下使用这个。 – Laurence 2012-02-15 08:06:58

+0

正如其他人所说的swap()技巧或shrink_to_fit()将清理向量。内存将被回收或不依赖于库或编译器的实现。由于优化原因,他们通常不会这样做。 – Jagannath 2012-02-15 09:38:34

11

有两个原因的过程中保持记忆:

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

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