c++memoryboostmemory-leaksptr-vector

C++ leaking memory with boost::ptr_vector


When opening up the task manager to see the memory usage, it will begin with .3MB memory used. After adding 100,000 objects to the ptr_vector, there is 2.3MB of memory used. After using .clear() on the vector, the memory goes to .8-.9MB. What is the cause of this increased memory usage?

Here's the code:

#include <iostream>
#include <boost/ptr_container/ptr_vector.hpp>

class T {
public:
    static int nObjects;
    T() {
        nObjects++;
    }
    ~T(){
        nObjects--;
    }
};

int T:: nObjects = 0;

int main() {
    boost::ptr_vector<T> vec;
    char pause;
    std::cout << "Press any key to continue: ";
    std::cin >> pause;

    for(int i=0; i<100000; i++) {
        vec.push_back(new T);
    }

    std::cout << T::nObjects << " objects created." << std::endl;

    std::cout << "Press any key to continue: ";
    std::cin >> pause;

    vec.clear();
    std::cout << T::nObjects << std::endl;

    std::cout << "Press any key to exit: ";
    std::cin >> pause;
    return 0;
}

Thanks for the help.


Solution

  • There is another big chunk of memory that it seems you're forgetting about: the space allocated in vec to hold the pointers.

    This statement:

    vec.clear();
    

    deleted all the Ts that you created with new, but it did not release the memory that vec itself allocated to hold all those pointers. If you call vec.capacity() you'll see that vec still has enough space to hold at least 100000 T*.

    In order to free up that memory, use the swap idiom:

    boost::ptr_vector<T>().swap( vec );
    

    This creates a temporary ptr_vector which then takes vec's internal storage in the swap() call. Then when the temporary is destroyed at the ;, all the storage is released.