I have a number of situations where queues are being used, which can grow to sizes in the many hundreds. Unfortunately, there is no one-call-solution to emptying the queue, should it become necessary. I'm wondering if using a scoped queue to do a swap, and then let the scoped queue be destroyed, breaks any memory allocation/management rules?
The following snippet is an example of what I am proposing. Seems to work, unsure of results if used many times over long periods.
#include <cstdlib>
#include <iostream>
#include <queue>
int
main()
{
std::queue<int> foo;
foo.push(10);
foo.push(20);
foo.push(30);
std::cout << "size of before foo: " << foo.size() << '\n';
{
std::queue<int> bar;
swap(foo, bar);
}
std::cout << "size of after foo: " << foo.size() << '\n';
return 0;
}
Your code is fine. swap
will make foo
a default constructed std::queue
and when bar
is destroyed at the end of the scope it will release the memory that foo
was using. Since you aren't using new
or delete
there is no issue since std::queue
"does the right thing" (RAII types are a wonderful thing)
Effectively you've done
std::queue<int>{std::move(foo)}; // move foo into a temporary that is immediately destroyed to release the storage
but your method gives you a stronger guaranteed about the state of foo
. Your method leave foo
in a default constructed state, while the above method leaves it in a valid, but unspecified state.
Another option is to use one of the solutions provided in Is there a way to access the underlying container of STL container adaptors? to get the underlying container from foo
and call clear on it. That would look like
#include <cstdlib>
#include <iostream>
#include <queue>
// function from https://stackoverflow.com/a/29325258/4342498 by jxh: https://stackoverflow.com/users/315052
template <class ADAPTER>
typename ADAPTER::container_type & get_container (ADAPTER &a)
{
struct hack : ADAPTER {
static typename ADAPTER::container_type & get (ADAPTER &a) {
return a.*&hack::c;
}
};
return hack::get(a);
}
int main()
{
std::queue<int> foo;
foo.push(10);
foo.push(20);
foo.push(30);
std::cout << "size of before foo: " << foo.size() << '\n';
get_container(foo).clear();
std::cout << "size of after foo: " << foo.size() << '\n';
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With