Reputation: 145
I have a coding assignment and I need to free whatever memory I allocate, so I'm trying to delete all the semaphores that my unique_ptr's are pointing to. The unique_ptrs are all in a map. The code snippets:
static map<string, unique_ptr<semaphore>> locks;
This is where all the semaphores are created using "new":
89 unique_ptr<semaphore>& up = locks[article.title];
90 if (up == nullptr) {
91 up.reset(new semaphore(6));
92 }
Later, I try to delete the semaphores in the following code:
160 for (map<string, unique_ptr<semaphore>>::iterator it = locks.begin(); it != locks.end();
161 ++it) {
162 cout << it->first << endl;
163 delete it->second;
164 }
And I get the compiler error:
news-aggregator.cc: In function âvoid processAllFeeds(const string&)â:
news-aggregator.cc:163:14: error: type âclass std::unique_ptr<semaphore>â argument given to âdeleteâ, expected pointer
make: *** [news-aggregator.o] Error 1
Upvotes: 1
Views: 10188
Reputation: 24269
The purpose of std::unique_ptr
is to own a memory allocation and automatically delete
it when it goes out of scope. IF you actually need to manually release the memory of a unique pointer early, there are ways to do it (reset
, etc).
In your specific case, the memory will be automatically freed if you delete the entry in the container.
for (auto it = locks.begin(), endit = locks.end(); it != endit; ++it) {
cout << it->first << endl;
delete it;
}
Here we are deleting the element of the container, which implicitly calls the unique_ptr
's destructor, which delete
s the memory it owns.
You can't use this pattern if container's iterators are invalidated by a delete.
If you have full C++11 support you could use:
for (auto it : locks) {
std::cout << it.first << '\n';
delete it.second;
}
But better still:
for (auto it : locks)
std::cout << it.first << '\n';
locks.clear();
The call to clear
will automatically call unique_ptr::~unique_ptr
on the value of each element. If you don't have C++11, just replace the for loop with an iterator loop, the call to clear
will have the same effect.
Upvotes: 0
Reputation: 145429
All you need to do to delete what a unique_ptr
points to is to reset
the unique_ptr
,
it->second.reset();
Upvotes: 5
Reputation: 7625
The error is clear:
delete
takes a pointer
as argument, not a unique_ptr
. Why you are trying to delete a pointer when you are using unique_ptr
for the very same purpose? The point of using smart pointers like unique_prt
or shared_ptr
is that they automatically delete the pointed object when no longer needed (i.e. out of scope) or you explicitly use reset
.
Upvotes: 4