correct use of delete

Apr 17, 2013 at 8:59pm
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?
Apr 17, 2013 at 9:03pm
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.
Apr 17, 2013 at 9:19pm
My bad, let me try and rephrase: How would I go about freeing the memory before the pointers are removed?
Apr 17, 2013 at 9:20pm
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.
Apr 17, 2013 at 9:30pm
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.
Apr 17, 2013 at 9:44pm
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.
Apr 19, 2013 at 9:56pm
Thank you - a great answer indeed.
Topic archived. No new replies allowed.