8

I am quite new to C++ memory management because unlike C, there are more hurdles to freeing all memory.

I am trying to successfully delete a pointer to vector of any type (i.e. vector * data)

/** 
 * We test the program in accessing vectors
 * with dynamic storage
**/
#include <iostream>
#include <vector> // you must include this to use vectors

using namespace std;

int main (void){
    // Now let's test the program with new and delete
    // for no memory leaks with vectors (type safe)
    // however, just calling delete is not enough to free all memory
    // at runtime
    vector <int> * test_vect = new vector <int> (10,5);

    // Print out its size
    cout << "The size of the vector is " << test_vect->size()
         << " elements" << endl;

    // run through vector and display each element within boundary
    for (long i = 0; i < (long)test_vect->size(); ++i){
        cout << "Element " << i << ": " << test_vect->at(i) << endl;
    }

    delete test_vect;
    return EXIT_SUCCESS;
}

However, I get a memory leak after using valgrind

==2301== HEAP SUMMARY:
==2301==     in use at exit: 4,184 bytes in 2 blocks
==2301==   total heap usage: 4 allocs, 2 frees, 4,248 bytes allocated
==2301== 
==2301== LEAK SUMMARY:
==2301==    definitely lost: 0 bytes in 0 blocks
==2301==    indirectly lost: 0 bytes in 0 blocks
==2301==      possibly lost: 0 bytes in 0 blocks
==2301==    still reachable: 4,096 bytes in 1 blocks
==2301==         suppressed: 88 bytes in 1 blocks

How can I be able to get rid of all traces of memory leaks with pointer to vector (i.e. at runtime)?

user123
  • 8,970
  • 2
  • 31
  • 52
JBRPG
  • 141
  • 1
  • 2
  • 10
  • 4
    `vector * test_vect = ...` defies the very purpose why vector exists in the first place. – Nawaz Apr 15 '13 at 02:30
  • 1
    Why are you using pointers with vectors..? – Rapptz Apr 15 '13 at 02:31
  • 1
    "because unlike C, there are more hurdles to freeing all memory." Wat. – GManNickG Apr 15 '13 at 02:32
  • 9
    Whether or not he's in his right mind using the pointer to a vector of ints is not quite the issue: what seems like a simple program is leaking memory. Let's try to help him figure out why, and later tell him why making a pointer to a vector is silly. –  Apr 15 '13 at 02:32
  • 3
    I don't see a leak. http://stackoverflow.com/questions/3840582/still-reachable-leak-detected-by-valgrind – Anthony Apr 15 '13 at 02:34
  • @anthony-arnold True. I can't see one either. Edit: OH GOD HERP DERP I CAN'T READ VALGRIND SAYS THERE IS NO LEAK. Lulz. Now we can get back to how silly this guy is. :D –  Apr 15 '13 at 02:34
  • 1
    The 4,096 bytes that are `still reachable` are not indicative of a memory leak – Charles Salvia Apr 15 '13 at 02:38
  • This code looks like it was written by a tutor or lecturer as a demonstration. While the use of dynamic memory here is questionable, the code is syntactically and semantically correct. For the reason why valgrind reports 4k of still-reachable bytes, see the link in my other comment. – Anthony Apr 15 '13 at 02:38

4 Answers4

22

For starters, I don't believe there is a leak. Did you properly read the Leak Summary you posted for the program?:

==2301== LEAK SUMMARY:
==2301==    definitely lost: 0 bytes in 0 blocks
==2301==    indirectly lost: 0 bytes in 0 blocks
==2301==      possibly lost: 0 bytes in 0 blocks
==2301==    still reachable: 4,096 bytes in 1 blocks
==2301==         suppressed: 88 bytes in 1 blocks

You've lost 0 bytes in 0 blocks. valgrind can't find any definite, indirect, or possible leaks. Your program is just fine.

As an aside: You... really shouldn't be using new or delete in this situation with that vector. C++, exactly like C, has things that come into and go out of scope on the stack if you declare them as regular variables. The following code achieves exactly what you did in your question, without the use of new and delete:

int main (void){
    // Now let's test the program with new and delete
    // for no memory leaks with vectors (type safe)
    // however, just calling delete is not enough to free all memory
    // at runtime (ThePhD: it is, actually!)
    vector <int>  test_vect(10,5);

    // Print out its size
    cout << "The size of the vector is " << test_vect.size() 
         << " elements" << endl;

    // run through vector and display each element within boundary
    for (long i = 0; i < (long)test_vect.size(); ++i){
        cout << "Element " << i << ": " << test_vect.at(i) << endl;
    }

    // ( ThePhD: Look ma, no deletions! )
    return EXIT_SUCCESS;
}

The stack will clean itself up magically, because std::vector has a destructor that cleans up its resources when it goes out of scope. You don't need to make it dynamic and put it on the heap / free-store area of program memory, when the stack will do it just fine.

Also, it sounds like you come from C, so I'll take the time to say: Welcome to C++. :D

user123
  • 8,970
  • 2
  • 31
  • 52
  • 2
    <3 @Rapptz for letting me know how to actually read Valgrind. :D –  Apr 15 '13 at 04:40
  • 1
    Although your suggestion works for small and simple programs, What would I do if I actually have to make a dynamically-allocated memory for a vector? The vector that lasts beyond a function call. – JBRPG Apr 15 '13 at 13:54
  • @JBRPG You pass your vector as a return value (which is fast because C++ now has `std::move` and friends) or you allocate the vector dynamically and keep track of it yourself. You can also do `std::unique_ptr>` and this will have the same semantics as a pointer to a std::vector, but with automatic deletion after you passed in a new vector. You can also pass things by reference in C++'s functions, operate on them, and the value after the function exists will be modified directly. It's a great time to C++. :D –  Apr 15 '13 at 16:50
6

I think this can be the answer. As far as C++ is concerned there is no leak here.

stardust
  • 5,918
  • 1
  • 18
  • 20
3

The whole purpose of those container classes is to do memory management for you, allocation, reallocation and deallocation. You put the container on the stack, it internally keeps its contents dynamically allocated, and when the container instance is deleted, it automatically deletes the dynamically allocated data.

Dynamic instantiation of the container itself defeats the purpose and is almost always entirely pointless.

And yes, in your case, the vector is really deleted.

dtech
  • 47,916
  • 17
  • 112
  • 190
  • I have to agree with you because as I searched through other questions, the majority of posts confirmed that vector is a dynamic memory class wrapper, which relieves me from having to manually put new and delete – JBRPG Apr 15 '13 at 16:39
  • 2
    Its not just vector, there are numerous container classes in the C++ standard library and even more in libraries like Qt or boost. – dtech Apr 15 '13 at 16:50
-3

I think you need to call

if(test_vect != 0)
{
   if(!test_vect->empty())
      test_vect->clear();
}

before deleting it