correct use of delete

Please consider this snippet

1
2
3
4
5
6
7
8
9
10
11
int main() {
    std::vector<int*> intPointers;
    int* ip;

    for(int i=0; i<5; i++) {
        ip = new int;
        intPointers.push_back(ip);
    }
    intPointers.erase(intPointers.begin());
    intPointers.pop_back();
}


At this point two of the pointers are gone from the vector, but the memory is still allocated. How do I free the memory?
At this point two of the pointers are gone from the vector, but the memory is still allocated. How do I free the memory?


You don't. It's been irrevocably leaked.
My bad, let me try and rephrase: How would I go about freeing the memory before the pointers are removed?
One of the reasons you should not rely on deleting manually. Let a smart pointer do it:

1
2
3
4
5
6
7
8
std::vector< std::unique_ptr<int> > intPointers;

for(int i=0; i<5; i++) {
    intPointers.push_back( std::unique_ptr<int>( new int ) );
}

intPointers.erase(intPointers.begin());  // no worries, no leak
intPointers.pop_back();  // ditto.  No problem. 



Of course, in this trivial example, you don't need pointers at all and can just push normal ints into the vector.
Of course, in this trivial example, you don't need pointers at all and can just push normal ints into the vector.


No of course. In the 'real' code, pointers to vector of objects are pushed back.

I'm not familiar with smart pointers, but I take it the pointer frees the memory before it is removed.

I was thinking more along the lines of
delete intPointers.at(n);

But I'm uncertain if this actually works.
I'm not familiar with smart pointers, but I take it the pointer frees the memory before it is removed.


You should get familiar with them. RAII should always (barring some extreme circumstances) be used as it provides the best defense against leaks and other issues caused by mismatching initialization/deinitialization.

unique_ptr, specifically, will delete the object in its destructor. Ensuring that as soon as the unique_ptr goes out of scope (ie: removed from the vector), the pointed to object will be deleted.


I was thinking more along the lines of
delete intPointers.at(n);

But I'm uncertain if this actually works.


Yes that works but is not ideal.

You'll have to make sure that you delete every element upon removal. This includes the "emptying" of the vector when the vector is destructed.

If you are manually deleting things, you will have to go through an delete all entries before the vector goes out of scope, or else everything contained in the vector will leak.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void someFunc()
{
    std::vector<int*> foo;

    // ... add a bunch of new'd stuff to foo here ...

} // <- MEMORY LEAK

// to correct... you must delete everything in the vector manually before it goes out of
//  scope

void someFunc()
{
    std::vector<int*> foo;

    // ... add a bunch of new'd stuff to foo here ...

    while( !foo.empty() )
    {
        delete foo.back();
        foo.pop_back();
    }
} // <- no more leak


// but even that doesn't necessarily protect you all the time....

void someFunc()
{
    std::vector<int*> foo;

    // ... add a bunch of new'd stuff to foo here ...

    if( something )
        return;   // MEMORY LEAK

    someRoutineThatThrowsAnException();  // MEMORY LEAK


    while( !foo.empty() )
    {
        delete foo.back();
        foo.pop_back();
    }
}


So yeah. avoid manual deletions. Use smart pointers.
Thank you - a great answer indeed.
Topic archived. No new replies allowed.