开发者

Why does this C++ program cause a memory leak?

开发者 https://www.devze.com 2023-02-09 18:21 出处:网络
Consider the following piece of code: char* str1 = new char [30]; char* str2 = new char [40]; strcpy(str开发者_如何学Go1, \"Memory leak\");

Consider the following piece of code:

char* str1 = new char [30];    
char* str2 = new char [40];   

strcpy(str开发者_如何学Go1, "Memory leak");    
str2 = str1;     

delete [] str2;     
delete [] str1; 

Why does the above program cause a memory leak? How do I avoid this?


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.


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.


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; 


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号