C++ 防止STL容器中的内存释放
我有一个STL容器(std::list),我一直在重复使用它。我的意思是我C++ 防止STL容器中的内存释放,c++,memory-management,stl,C++,Memory Management,Stl,我有一个STL容器(std::list),我一直在重复使用它。我的意思是我 将多个元素推入容器中 在处理过程中移除元素 清理容器 冲洗并重复多次 使用callgrind评测时,我看到大量调用new(malloc)和delete(free),这可能非常昂贵。因此,我正在寻找某种方法,最好预先分配相当多的元素。我还希望我的分配池继续增加,直到达到一个高水位线,并希望分配池继续挂起内存,直到容器本身被删除 不幸的是,标准分配器不断调整内存池的大小,所以我正在寻找一些分配器,它可以在不必编写自己的内存池
new
(malloc
)和delete
(free
),这可能非常昂贵。因此,我正在寻找某种方法,最好预先分配相当多的元素。我还希望我的分配池继续增加,直到达到一个高水位线,并希望分配池继续挂起内存,直到容器本身被删除
不幸的是,标准分配器不断调整内存池的大小,所以我正在寻找一些分配器,它可以在不必编写自己的内存池的情况下执行上述操作
是否存在这样的分配器?在哪里可以找到这样的分配器
我使用GCC在Linux上工作,使用STLPort在Android上工作
编辑:Placement
新建
没问题,我想最小化的是堆遍历,这很昂贵。我还希望我的所有对象尽可能靠近,以最大限度地减少缓存未命中。听起来您可能只是使用了错误类型的容器:对于列表,每个元素占用单独的内存块,以允许单独的插入/删除-因此列表中的每个添加/删除表单都需要单独的new()/删除()
如果可以改用std::vector
,则可以在添加项目之前保留所需的大小
对于删除,通常最好不要单独删除项目。只需调用容器上的clear()
,将其清空即可。它
编辑:您现在已经在评论中明确表示,您的“在处理过程中删除元素”步骤是从列表中间删除元素,并且不能使迭代器无效,因此切换到向量是不合适的。我暂时不回答这个问题(为了评论线索!)你可以尝试使用测试你的应用程序,我在我的一些项目中看到了一些很好的改进(虽然手头没有数字,对不起)
编辑:似乎代码/下载已移到那里:评论太短,因此我将发布我的想法作为答案
在国际海事组织,在这种情况下,新建/删除只能来自两个地方
我相信由于各种原因,std::list
与通常的列表一样,是通过某种节点实现的。因此,元素的每次插入和移除都必须导致节点的新建/删除。此外,如果T
类型的对象在c'tor/d'tor中有任何分配和解除分配,那么它们也将被调用
通过在现有节点上重复而不是删除它们,可以避免重新创建标准内容。如果您想将其压缩到c级,可以使用and或
尽管如此,对于创建的每个对象,都必须称为析构函数。我认为避免创建和破坏的唯一方法是在容器上重复时使用T::operator=
,或者如果适合您的情况,可以使用一些c++13移动东西。分配器是为与std::list
一起使用而设计的
该文档声称“如果您非常关心性能,请在处理诸如std::list
之类的容器时使用boost::pool\u分配器
,在处理诸如std::vector
之类的容器时使用boost::pool\u分配器
”
请注意,boost::fast_pool_allocator
是一个单例,默认情况下它从不释放分配的内存。但是,它是使用实现的,您可以通过调用静态函数boost::singleton_pool::release_memory()
和boost::singleton_pool::purge_memory()来释放内存
new和delete可能是容器中包含的对象析构函数和构造函数,这使容器变得更加复杂unavoidable@fatih_k但是,只有当列表中包含指向动态分配对象的指针时,这才有效。我相信OP可能知道要避免这种情况。@Angew,只有当包含的元素是对象而不是指针时,才会调用对象的析构函数。容器不拥有指针的所有权Placement new可以,我只想最小化对MALOC和FRILI的调用,认为您应该查看这些分配器实例:-除了我想删除列表中间的元素,而没有内存拖曳:STD::vector将entail@doron内部的订单是否包含物质?如果没有,您只需将要删除的内容与最后一个元素交换,然后pop_back()
。没有洗牌。@doron不过,记忆洗牌可能比你想象的要少。请看Bjarne Stroustrup解释向量vs列表的好处(从44:40开始)简言之,即使您删除了很多内容并插入了很多内容,列表中的线性搜索时间也完全支配着处理时间,因为对象分散在内存中,这会影响cpu缓存。@doron“除了我想删除列表中间的元素,而没有内存更新:STD::向量将带来”——你已经使用了一个分析器,所以只需测试一个测试,比较向量的洗牌疯狂速度到列表的分配疯狂。结果可能是令人惊讶的(并且可能粉碎你对Big-O符号的信任);).@doron那么这确实是一个完美的(如果不是唯一合理的话)一个std::list
的用例,是你应该在对这个答案的第一次评论中提到的,而不是performance参数,因为前者是你不能使用std::vector
的一个很难解释的原因,而不是一个要讨论的伪原因