1

I have a C++98 test code. This code make a horrible memory lake. Why? Memory consumption after the release of pointers is the same as before the release.

#include <iostream>
#include "string.h"


using namespace std;

void test();

int main() {
    test();
    cout << "Freed" << endl;
    int input;
    cin >> input;
    cout << "Good bye" << endl;
    return 0;
}

void test() {
    int input;
    int count = 40000000;
    const char *str = "9 770123456789123456123";
    char **pMsg = new char *[count];
    cout << "Register: " << count << endl;
    cin >> input;
    for (int i = 0; i < count; i++) {
        pMsg[i] = new char[strlen(str) + 1];
        strcpy(pMsg[i], str);
    }
    cout << "Full pointers" << endl;
    cin >> input;

    for (int i = 0; i < count; i++) {
        delete[] pMsg[i];
    }
    delete[] pMsg;
}
  • 1
    [Why should you use strncpy instead of strcpy?](http://stackoverflow.com/questions/1258550/why-should-you-use-strncpy-instead-of-strcpy) – Jonny Henly May 22 '15 at 22:26
  • 1
    @JonnyHenly you're right, but he uses `strlen()` before, so if there was a missing null terminator, it's already too late ;-) – Christophe May 22 '15 at 22:32
  • How do you determine that there is a memory leak? Note that the C++ run-time is unlikely to return small individual blocks of memory to the system when using `delets[]`. Instead it is more likely to keep them and use them for later requests for memory. – Dietmar Kühl May 22 '15 at 22:59
  • An application memory consumption will always increase and never decrease. The only thing you're doing when you release memory is ensure that the next malloc/new will not necessariliy increase the memory usage. In other words, you allocate 1mb and free it, memory usage becomes 1 mb. You allocate another 512 K and your memory allocation doesn't change. – Mustafa Ozturk May 23 '15 at 00:06

2 Answers2

3

In principle your memory doesn't leak, because you've a delete[] fore every new[].

But when you allocate huge amounts of memory (and even in general, whenever you allocate memory), you should consider the case the allocation fails:

    ...
    try {
        test();
    }
    catch(bad_alloc) {
        cerr << "No more memory !" <<endl; 
    }
    ...

The fact that an exception is raised (which happens here), will cause your code to leave test() before the deletes take place. So due to the exception, your memory will leak.

Remark: The best way to avoid such memory leaks is to use the RAII idiom: you make memory allocation only inside an object, and you free the memory in the object's destructor. As all objects that go out of scope will be deleted, this will make sure that memory freing always takes place, even in case of exceptions.

Christophe
  • 68,716
  • 7
  • 72
  • 138
1

"Memory consumption after the release of pointers is the same as before the release". This is not indicative, many implementations of free will not usually return the memory to the OS, instead "recycling" it for future allocations. See this question.

Community
  • 1
  • 1
Alberto M
  • 1,057
  • 8
  • 24
  • 1
    Yeah!!! After reading your comment, I rewrote the code, invoking 2 times the "test()" method. Effectively the memory was returned to the OS at second invocation. This is a good response that knows only one old salt sea. ;-) Thanks. – Cristian Calabrán May 22 '15 at 23:42