Reputation: 36681
Consider the following piece of code:
char* str1 = new char [30];
char* str2 = new char [40];
strcpy(str1, "Memory leak");
str2 = str1;
delete [] str2;
delete [] str1;
Why does the above program cause a memory leak? How do I avoid this?
Upvotes: 5
Views: 1838
Reputation: 4206
Because you're deleting str1 (the memory it points to) twice and you don't delete the memory allocated under where str2 was first pointing to.
EDIT: I'm not sure what you're trying to achieve.
char* str1 = new char [30];
// str1 = 0x00c06810; (i.e.)
char* str2 = new char [40];
// str2 = 0x00d12340; (i.e.)
strcpy(str1, "Memory leak");
// delete [] str2; should be here
str2 = str1;
// now str2 == str1, so str2 = 0x00c06810 and str1 = 0x00c06810
// deleting 0x00c06810
delete [] str2;
// deleting 0x00c06810 once again
delete [] str1;
// 0x00d12340 not deleted - memory leak
If you want that assignment (str2 = str1) then delete str2 first.
Upvotes: 20
Reputation: 2499
make pointers to be const pointers
The problem is that you allocate memory for two arrays, you get two pointers, then you overwrite address of the second array with address of first array. So you try to free memory of the first array
Upvotes: 2
Reputation: 373462
The above doesn't just lead to a memory leak; it causes undefined behavior, which is much, much worse.
The problem is in the last three lines:
str2 = str1;
delete [] str2;
delete [] str1;
If we ignore this first line, then the last two lines correctly reclaim all the memory allocated in this function. However, this first line sets str2
to point to the same buffer as str1
. Since str2
is the only pointer in the program to the dynamic memory it references, this line leaks the memory for that buffer. Worse, when you then execute the next two lines to clean up the two pointers, you delete the same block of memory twice, once through str2
and once through str1
. This leads to undefined behavior and often causes crashes. Particularly malicious users can actually use this to execute arbitrary code in your program, so be careful not to do this!
But there's one higher-level issue to take into account here. The whole problem with this setup is that you have to do all your own memory management. If you opt to use std::string
instead of raw C-style strings, then you can write the code like this:
string str1 = "Memory leak"; // Actually, it doesn't. :-)
string str2;
str2 = str1; // Okay, make str2 a copy of str1
// All memory reclaimed when this function or block ends
Now, there's no need to explicitly manage the memory, and you don't have to worry about buffer overruns or double-frees. You're saved by the magic of object memory allocation.
Upvotes: 21
Reputation: 49269
Every object needs to be pointed-at in the memory.
The pointers keep track of where the data is (remember that your RAM memory is HUGE compared to the little array).
So in your case, you're losing the second array's place in memory. So there's an array lost somewhere in memory that you can't get to.
When you do str2 = str1;
str2 points now to the block of memory that str1 pointed to. So there's nothing left to point at the second array.
Upvotes: 0
Reputation: 6030
You assign str1 pointer to str2 pointer, so delete[]str1 and delete[]str2 free only memory pointed by str1 (str2 points to the same memory). You need to free str2 memory before loosing pointer to it (before assigning str1 to str2)
The correct way is
char* str1 = new char [30];
char* str2 = new char [40]; //or just don't allocate this if You don;t need it
strcpy(str1, "Memory leak");
**delete [] str2;**
str2 = str1;
delete [] str1;
Upvotes: 4