Why doesn't std::queue shrink its memory after popping elements?
Basically std::queue
is an Adapter Container - it is not a container by its own, but a thin wrapper around other container.
For example, lets take a look at the queue signature:
template <class T, class Container = deque<T> > class queue;
as you can see, T
is the type of the element stored in the queue, and Container
is the underlying container.
and this is the answer to your question: different containers handles memory differently. the underlying deque may or may not shrink, but it is up to the deque inside to decide.
you can use std::list
as your underlying container as well. in this case, each pop deletes the underlying list node memory.
you can also write your own or modify existing container to match your own memory-management patterns. your container needs to support some methods (such as push_back
, pop_front
) which you can read in the relevant online documentation.
Here is an example to a deque
adapter which shrinks in capacity every 1024 pop
calls:
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>>;
Do note however, that shrinking in capacity means moving or copying the queue elements to the new lean chunk, the memory consumption will be smaller, but the performance may degrade.
Any memory the queue manages will be released when the queue goes out of scope.
However, even then memory may not be released back to the OS because the standard library makes the assumption that if you used the memory before, you may well need it again.
The specifics of this are taken care of in malloc/free in the specific c runtime library your program is linked against.
Is this an embedded system where memory is tight? (in which case perhaps consider fixed-size containers), or is it running on a server/desktop/ipad? (in which case tell your boss to stop worrying about things he doesn't understand).