std::列出元素删除后节点的内存回收
std::list node's memory recycling after element removal
我很想知道当元素从列表中删除时,STL的std::list
是否实现了某种形式的节点的"内存节省/回收",以重用先前节点占用的内存,以便将来向列表中添加新元素。
。当调用std::list::pop_back()
来删除链表的最后一个元素时,该节点所占用的内存是否被保存,以至于当使用push_back()
将新元素添加到链表的末尾时,没有动态内存分配给新节点,而只是先前删除的节点的内存被回收?
这有点类似于std::vector
,它有闲置的容量。
这是一个相当古老的问题,但当我在谷歌上寻找有关这方面的信息时,它出现了。
当一个项目从std::list
中删除时,该项目的内存将被释放并销毁,除非您提供一个替代Allocator,该Allocator在被要求释放内存时做一些不同的事情。标准库容器具有非常明确的内存特征,我怀疑任何现代标准库实现都试图重用内存。操作系统可能试图提高分配和释放的效率,但默认的分配器仍然会进行系统malloc/free调用,我认为这是您试图避免的昂贵的事情。
实现这一点的通用或通用方法是编写您自己的分配器。
只是使用std::list
虽然,如果你想重用内存,你可以尝试使用splice()
来重新链接项目和另一个可重用项目列表。或者如果你同时添加一个项目并删除另一个项目(例如,一个缓冲区或固定大小的队列,每当一个项目被添加到前面时,项目就从后面被删除),然后将旧项目拼接到新位置并替换其内容,等等。
关于splice的更多信息:https://en.cppreference.com/w/cpp/container/list/splice
不要混淆splice()
参数。(文档上写着"另一个列表";但也可能是同一个名单;注意,迭代器不会失效。)
请注意,这是自定义内存管理的边界,因此请确保您有一个清晰,定义良好的算法来执行此操作。
与c++一样,您需要注意对象/值何时被复制、分配和可能的移动。仔细阅读std::list
的文档,了解它何时分配和复制数据。https://en.cppreference.com/w/cpp/container/list
下面的示例将列表中的最后一个元素重新链接到前面:
#include <list>
#include <iostream>
#include <algorithm>
int main() {
std::list<int> l{1, 2, 3, 4};
std::for_each(l.begin(), l.end(), [](int i){std::cout << i << ", ";});
std::cout << "n";
auto topos = l.begin();
auto frompos = l.end();
frompos--;
l.splice(topos, l, frompos);
std::for_each(l.begin(), l.end(), [](int i){std::cout << i << ", ";});
std::cout << "n";
return 0;
}
修改上面的代码,将结构体或对象存储在构造、销毁、复制和移动时打印出来的列表中,然后尝试使用insert()
、emplace()
、remove()
、pop_back()
等,看看会发生什么。
- 我们可以删除链表中静态内存中的节点吗
- 避免在使用链接列表从 deque 中删除最后一个节点时出现内存泄漏
- 对树节点使用 CString 时出现内存泄漏
- 如何在 C++11 的内存池中分配 std::map 的内部RB_tree节点?
- C 中的学生指针节点列表中的内存泄漏
- 两个单链列表共享同一个节点和析构函数两次删除相同的内存
- 将节点添加到链接列表中,而无需明确分配内存空间(无需使用新)
- 在声明节点创建链接列表时,为什么静态内存分配不起作用
- 在C++中设置节点的内存地址
- C++ 如何在不丢失内存的情况下删除节点
- 当我通过删除临时节点来释放内存时,我会得到读取访问违规行为.但是只有当我返回错误语句时
- 如何从链表上的节点为分配的类释放内存
- 当两个节点相互指向时,不可避免的内存泄漏
- 使用节点::缓冲区包装现有内存
- “算子删除”如何为链表节点释放内存块
- 我们需要为链表节点分配内存吗
- 通过池分配器中的内存地址访问可用列表节点时出现问题
- c++ STL列表节点内存分配中的段错误
- std::列出元素删除后节点的内存回收
- 在C/ c++中,链表只有头指针分配在堆栈中,其他节点分配在堆中.这可能导致内存泄漏