C++ C++;在OSX 10.8上

C++ C++;在OSX 10.8上,c++,list,memory,vector,stl,C++,List,Memory,Vector,Stl,我在实现向量时遇到内存问题。代码如下: struct structure{ vector< list<size_t> > Ar; structure(int n){ Ar.reserve(n); for(size_t i =0; (int) i< n;i++){ list<size_t> L; Ar.push_back(L); }

我在实现向量>时遇到内存问题。代码如下:

struct structure{
    vector< list<size_t>  > Ar;

    structure(int n){
        Ar.reserve(n);
        for(size_t i =0; (int) i<  n;i++){
            list<size_t> L;
            Ar.push_back(L);
        }
    }

    ~structure(){
       vector<list<size_t> >::iterator it = Ar.begin();
       while(it < Ar.end()){
           (*it).clear();
           ++it;
       }
       Ar.clear();
    }


};

int main() {

    for(size_t k = 0; k <100 ; k++){    
        structure test_s = structure(1000*(100 - k));
    }
    return 0;
}
struct结构{
向量Ar;
结构(int n){
应收账款准备金(n);
对于(大小i=0;(int)i对于(size_t k=0;k我没有发现该代码中有任何漏洞,但有很多不需要的代码。简化的代码是:

struct structure{
    vector< list<size_t>  > Ar;

    structure(int n): Ar(n) // initialize the vector with n empty lists
    {
    }

    // destructor unneeded, since Ar will be destroyed anyway, with all of its elements.
};
struct结构{
向量Ar;
structure(int n):Ar(n)//使用n个空列表初始化向量
{
}
//不需要析构函数,因为Ar及其所有元素都将被销毁。
};
但这并不能回答你的问题

堆内存分配并不意味着物理内存分配。现代操作系统使用虚拟内存,通常由分页文件支持。堆内存分配从虚拟内存获取内存,操作系统决定是否需要更多或更少的物理内存。将内存释放到虚拟内存并不意味着释放物理内存(如果其他流程不需要,为什么要在当时这样做?)

此外,堆内存分配不会直接转换为虚拟内存分配。通常,虚拟内存分配的粒度较大,因此不适用于较小的分配。然后,堆管理器分配虚拟内存块,并对所有堆分配进行管理。(如果虚拟内存不足,堆管理器将要求更多)。何时释放未使用的虚拟内存块取决于堆管理器的实现方式

要完成更复杂的事情,根据分配/取消分配模式以及堆的实现方式,分配和取消分配不同大小的内存将产生堆碎片


物理内存并不是内存泄漏的好指示器。这类程序可能是更好的私有(虚拟)内存或类似的内存。

< P> C++分配器在完成操作时不一定会将内存返回到内存中,但通常会保持它的位置,因为您可能很快就会需要它。 我不熟悉OS X分配器的详细信息,但分配器从操作系统中以较大的块获取内存,然后将其作为单独的池来处理是很常见的。
这可能就是你所看到的,当第一块内存被填满时,内存会突然增长。
也有可能您正在通过“较大”分配和“较小”分配之间的某个阈值,而您只是看到一个添加的池用于稍微较小的事情-一些分配程序会这样做。
当然,原因也可能完全不同

当您对每个请求使用相同大小时,差异很可能是因为分配器很容易使用最近释放的相同大小的块来填充请求

当块大小不同时,分配一个大小不同的新块比将一个空闲块分成两个更小的块要快。
(不幸的是,这也会导致内存碎片。如果您得到许多分散的小数据块,尽管总空间足够大,但可能无法满足大型分配请求。)

总而言之:如今,内存分配器和操作系统相当复杂,你无法通过观察内存分配的增长来确定内存泄漏。

我相信valgrind和Instruments在你的情况下。

你的析构函数什么都不做,你的构造函数可以写成
structure(int n):Ar(n){}
。这里没有内存泄漏。规则为零。您的类不需要析构函数。我甚至懒得检查它是否是原因。您是如何发现您的程序有内存泄漏的?您知道您的程序不必(立即)将内存返回操作系统的?我在活动监视器中观察到内存增加。这是错误的吗?感谢关于构造函数和析构函数的提示。我很确定这不是原因;如果我向构造函数传递一个文本,我就不会遇到问题。谢谢!我将尽量减少分配时使用不同大小的内存。在我看来,列表应该显示内存的不确定性:由于对象可以动态地添加和删除到列表中,分配器不会对使用的内存量感到困惑吗?对不起,我是这个网站的新手:我应该打开一个新的线程来问这个问题吗?谢谢!我将更改我正在查看的内存值。有什么方法可以帮助分配器使用fr吗程序运行时内存分配?我还将清除浪费的代码!我更改了代码以避免及时分配。现在,我创建了一个结构对象,为整个for循环的向量分配足够的内存。我没有使用析构函数清除内存,而是添加了一个函数来清除l的内容这对于我的程序的内存管理来说已经足够了,因为列表的内容比容器本身大得多,并且内存分配不再有跳跃!感谢大家的贡献!