mr_*_*air 5 c++ memory memory-leaks
考虑以下代码:
char* str1 = new char [30];
char* str2 = new char [40];
strcpy(str1, "Memory leak");
str2 = str1;
delete [] str2;
delete [] str1;
Run Code Online (Sandbox Code Playgroud)
为什么上述程序会导致内存泄漏?我该如何避免这种情况?
tem*_*def 21
以上不仅会导致内存泄漏; 它导致未定义的行为,这更糟糕.
问题出在最后三行:
str2 = str1;
delete [] str2;
delete [] str1;
Run Code Online (Sandbox Code Playgroud)
如果我们忽略第一行,那么最后两行正确地回收了此函数中分配的所有内存.但是,第一行设置str2为指向相同的缓冲区str1.由于它str2是程序中唯一指向它引用的动态内存的指针,因此该行会泄漏该缓冲区的内存.更糟糕的是,当你执行接下来的两行来清理两个指针时,你会删除相同的内存块两次,一次通过str2,一次通过str1.这会导致未定义的行为并经常导致崩溃.特别是恶意用户实际上可以使用它来执行程序中的任意代码,所以小心不要这样做!
但是这里有一个更高级别的问题需要考虑.此设置的整个问题是您必须执行所有自己的内存管理.如果您选择使用std::string而不是原始C风格的字符串,那么您可以编写如下代码:
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
Run Code Online (Sandbox Code Playgroud)
现在,没有必要显式管理内存,您不必担心缓冲区溢出或双重释放.你被对象内存分配的魔力所拯救.
Ste*_*fan 20
因为您正在删除两次str1(它指向的内存)并且您不删除在str2首先指向的位置下分配的内存.
编辑:我不确定你想要实现的目标.
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
Run Code Online (Sandbox Code Playgroud)
如果你想要那个赋值(str2 = str1),那么首先删除str2.