Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I want to erase all memory in a container. Currently I'm using this :

template<typename Cont>
void clear_mem(Cont &container)
{
    while (!container.empty())
    {
        delete container.back();
        container.pop_back();
    }
}
  1. Should the operation of deleting the memory held by the contents be separated by clearing the container ?
  2. Is it pointless to make this function a template, since it can only operate on vector and list ?
share|improve this question
    
Why are you putting pointers in your containers? –  Loki Astari May 19 at 21:30
    
If you really need a container full of pointers, where the container owns what the pointers point at, you probably want to look into Boost ptr_vector. –  Jerry Coffin May 20 at 5:15

2 Answers 2

This assumes that the container holds raw pointer and it owns the pointers. it is a better idea to then let the container hold smart pointers.

These will automatically clear the object they hold when they get destroyed (using delete by default).

typedef std::unique_ptr<Type> Type_ptr;
std::vector<Type_ptr> container;

and use emplace to fill it;

container.emplace_back(std::make_unique<Type>());
share|improve this answer
2  
no raw new, please use container.emplace_back(make_unique<Type>()); instead. –  TemplateRex May 19 at 13:49
    
@TemplateRex good suggestion! Unfortunately, this is not supported by all compilers yet, since it was only introduced in C++ 14 (C++ 11 has only make_shared) –  lethal-guitar May 19 at 17:26
1  
@lethal-guitar I know, but even so, writing your own make_unique (or copy the one from the Standard proposal) in that case is better than raw new. –  TemplateRex May 19 at 17:46

Question 1

It depends. An std::vector won't actually release any underlying buffer memory even if it's no longer required, so you can't rely on removing the elements in order to free the memory used to store them.

e.g

std::vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

vec.clear();

//vec still owns a buffer large enough to hold its initial elements

Well, you could now reasonably say that "ok, no problem! I'll just use std::vector::resize". The problem with this method is that it only resizes the buffer when the requested size is bigger than the buffer's current size.

In order to free the memory allocated by the std::vector itself, the swap idiom is used, where you construct a new empty vector and you swap it with the original.

Continuing from the previous example

std::vector<int> empty{};
vec.swap(empty);

std::list also has a swap method, so implementing a template function that works for both using the swap idiom is possible, even though you don't need it for a list because the node used to store an element is released when its removed.

A more C++/STL way to do it would be

template<template<typename ElementType, typename Alloc> 
         class    ContType, 
         typename ElementType,
         typename Alloc>
void clear_mem(ContType<ElementType*, Alloc>& container)
{
    std::for_each(container.begin(), container.end(), [](ElementType* element) {
        delete element;
    });

    ContType<ElementType*, Alloc> empty{};
    container.swap(empty);
}

Of course such an implementation would only work for a container holding pointers to objects.

To conclude, releasing the underlying memory while removing elements is not possible with std::vector.

Question 2

No it's not, it very common to swap std::list for std::vector and vice versa, so using a template deleter would not break client code when a change actually happens.

share|improve this answer
1  
std::vector has a shrink_to_fit() so you don't need to swap it around (since C++11) –  ratchet freak May 20 at 8:18
    
@ratchetfreak According to the C++ standard it's not mandatory for shrink_to_fit to actually fulfil the request. Also the template won't work for an std::list. –  Erevis May 20 at 9:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.