gpt4 book ai didi

c++ - 为什么 std::queue 在弹出元素后不收缩内存?

转载 作者:可可西里 更新时间:2023-11-01 18:19:50 28 4
gpt4 key购买 nike

我写了一个使用 std::queue 的小程序

queue<double> the_queue;

for(int i = 0; i < 100; i++)
{
for(int j = 0; j < 5000; j++)
{
double d = 1.0 * (rand() % 1000);
the_queue.push(d);
}
}

printf("Done pushing\n");

while(!the_queue.empty())
{
the_queue.pop();
}

printf("Done popping\n");

我在 printf("Done pushing\n");printf("Done popping\n"); 处设置了 2 个断点,并检查程序的内存使用情况(显示在任务管理器中)当遇到断点时。在 Done pushing 时,内存使用量约为 34 MB,但在 Done popping 时,内存使用量仍约为 34 MB。这让我很吃惊!

这是为什么?有什么办法可以克服这个问题吗?

最佳答案

基本上 std::queue 是一个 Adapter Container - 它不是一个单独的容器,而是一个围绕其他容器的薄包装。

例如,让我们看一下队列签名:

template <class T, class Container = deque<T> > class queue;

可以看到,T是队列中存储元素的类型,Container是底层容器。

这就是您问题的答案:不同的容器以不同的方式处理内存。底层双端队列可能收缩也可能不收缩,但这取决于内部的双端队列。

您也可以使用 std::list 作为底层容器。在这种情况下,每个 pop 都会删除底层列表节点内存。

您还可以编写自己的容器或修改现有容器以匹配您自己的内存管理模式。您的容器需要支持一些方法(例如push_backpop_front),您可以在相关在线文档中阅读这些方法。

这是一个 deque 适配器的例子,它每调用 1024 次 pop 就会缩减容量:

template<class T>
class DequeAdapter{

private:
std::deque<T> m_Deque;
size_t m_PopCount;

public:
DequeAdapter():
m_PopCount(0){}

bool empty() const noexcept{
return m_Deque.empty();
}

size_t size() const noexcept{
return m_Deque.size();
}

T& front() noexcept{
return m_Deque.front();
}

const T& front()const noexcept{
return m_Deque.front();
}

T& back() noexcept{
return m_Deque.back();
}

const T& back()const noexcept{
return m_Deque.back();
}

void push_back(const T& t){
return m_Deque.push_back(t);
}

void push_back(T&& t){
return m_Deque.push_back(std::move(t));
}

void pop_front(){
m_Deque.pop_front();
m_PopCount++;
if (m_PopCount%1024U == 0U){
m_Deque.shrink_to_fit();
}
}

}


template <class T>
using LeanQueue = std::queue<T,DequeAdapter<T>>;

但请注意,缩容意味着将队列元素移动或复制到新的精益 block 中,内存消耗会更小,但性能可能会下降。

关于c++ - 为什么 std::queue 在弹出元素后不收缩内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38198621/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com