问题:vc6.0编辑器release版的delete是否释放堆空间?
详细问题:
我使用该书提供的代码,发现debug版下,运行导致程序崩溃,应该是两次释放堆空间导致的,重新使用release版编译,发现没有错误,调试一下,编译器做了些优化,代码大致如下od中:
00401020 /$ 53 push ebx
00401021 |. 6A 0A push 0A
00401023 |. E8 C4000000 call 004010EC ; new 10个字符
00401028 |. 8BD8 mov ebx, eax
0040102A |. 83C4 04 add esp, 4
0040102D |. 85DB test ebx, ebx
0040102F |. 74 26 je short 00401057 ; 判断申请空间是否成功
00401031 |. 56 push esi
00401032 |. 57 push edi
00401033 |. BF 40704000 mov edi, 00407040 ; ASCII "Hello"
00401038 |. 83C9 FF or ecx, FFFFFFFF
0040103B |. 33C0 xor eax, eax
0040103D |. F2:AE repne scas byte ptr es:[edi]
0040103F |. F7D1 not ecx
00401041 |. 2BF9 sub edi, ecx
00401043 |. 8BC1 mov eax, ecx
00401045 |. 8BF7 mov esi, edi
00401047 |. 8BFB mov edi, ebx
00401049 |. C1E9 02 shr ecx, 2
0040104C |. F3:A5 rep movs dword ptr es:[edi], dword p>
0040104E |. 8BC8 mov ecx, eax
00401050 |. 83E1 03 and ecx, 3
00401053 |. F3:A4 rep movs byte ptr es:[edi], byte ptr>
00401055 |. 5F pop edi
00401056 |. 5E pop esi
00401057 |> 53 push ebx ; 对象的首地址
00401058 |. E8 A3FFFFFF call 00401000 ; ShowMyString函数 尝试释放空间,但是没有成功
0040105D |. 83C4 04 add esp, 4
00401060 |. 85DB test ebx, ebx
00401062 |. 74 09 je short 0040106D
00401064 |. 53 push ebx
00401065 |. E8 46000000 call 004010B0 ; 调用析构函数 同样没有释放空间 这样是否存在内存泄露?
0040106A |. 83C4 04 add esp, 4
0040106D |> 5B pop ebx
0040106E \. C3 retn
发现调用delete时,空间并没有被释放,而且可以继续使用这样导致不会产生错误,但是main函数退出,这个空间也没有释放?这样会不会造成内存泄露?(对delete的实现机制不是很了解,忘高人指教一下)
同时修改代码如下:
#include <STDIO.H>
#include <STRING>
/************************************************************************/
/* 对象作为函数参数 资源释放错误
*/
/************************************************************************/
class CMyString{
private:
char * m_pString;
public:
CMyString(){ //申请堆空间,只要不释放,进程退出前将一直存在
m_pString = new char[10];
if(m_pString == NULL){
return ;
}
strcpy(m_pString,"Hello");
}
~CMyString(){
if(m_pString != NULL){
delete m_pString; //释放资源
m_pString = NULL;
}
}
char *GetString(){
return m_pString; //获得数据成员
}
char *SetString(char* str){
strcpy(m_pString,str);
}
};
void ShowMyString(CMyString MyStringCpy){
printf(MyStringCpy.GetString());
MyStringCpy.SetString("aaa");
}
void main(){
CMyString MyString;
ShowMyString(MyString);
printf("%s\r\n",MyString.GetString());
char *test = new char[10]; //重新申请空间 获得与MyString一样的起始地址,对空间进行操作(注:修改长度10 应该是在
块内就可以)
strcpy(test,"test");
delete test;
test = NULL;
printf("%s\r\n", MyString.GetString()); //重新获得信息 显示的是test,
}
发现MyString的字符串指针与test指向相同的地方,可以通过MyString操作test,这个还是不太明白,忘高人指教?
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)