前几天写代码,使用new操作符动态分配存储空间,本来是准备分配多个存储空间,可是形式用错了:
char *pc = new char(10);
本来是要分配10个字节类型的存储空间,但是在delete释放空间时却总是出错,提示damage。后来将()改为[]错误得以消除。C++中应该是对于原始数据类型可以看作对象对待,比如上面的语句,是分配一个字节的存储单元并初始化为10。当然也可以不初始化,如char *pc = new char();
贴一下调试的反汇编的代码:
36: char *pc1 = new char(); ;pc1地址为[ebp-4]
00405A28 push 1
00405A2A call operator new (00407eb0)
00405A2F add esp,4
00405A32 mov dword ptr [ebp-10h],eax
00405A35 mov eax,dword ptr [ebp-10h]
00405A38 mov dword ptr [ebp-4],eax
37: char *pc2 = new char(10); ;pc2地址为[ebp-8]
00405A3B push 1 ;分配内存单元字节数
00405A3D call operator new (00407eb0) ;调用new, 内部调用malloc在堆中分配
00405A42 add esp,4 ;平衡堆栈
00405A45 mov dword ptr [ebp-14h],eax ;将分配的内存单元地址送[ebp-14H], 堆栈中的临时存储单元; 以下为初始化代码
00405A48 cmp dword ptr [ebp-14h],0 ;和0比较,分配地址为0则不初始化
00405A4C je main+4Ch (00405a5c) ;为0转移到00405a5c
00405A4E mov ecx,dword ptr [ebp-14h] ;不为0则将[ebp-14h]中的保存的所分配的内存首单元地址送ecx
00405A51 mov byte ptr [ecx],0Ah ;将所分配的内存单元地初始化为10
00405A54 mov edx,dword ptr [ebp-14h] ;将所分配的内存单元首地址送edx
00405A57 mov dword ptr [ebp-28h],edx ;将此地址送中间变量, 地址为[ebp-28H]
00405A5A jmp main+53h (00405a63) ;初始化完成, 跳转到00405A63, 准备将所分配的内存单元首地址送pc2
00405A5C mov dword ptr [ebp-28h],0 ;分配的存储单元地址为0, [ebp-28H]为中间变量, 将[ebp-28H]存储单元赋值为0
00405A63 mov eax,dword ptr [ebp-28h]
00405A66 mov dword ptr [ebp-8],eax ;借助eax将所分配的内存单元地址送变量pc, pc地址为[ebp-8h]
38: char *pc3 = new char[10]; ;pc3地址为[ebp-0CH]
00405A69 push 0Ah
00405A6B call operator new (00407eb0)
00405A70 add esp,4
00405A73 mov dword ptr [ebp-18h],eax
00405A76 mov ecx,dword ptr [ebp-18h]
00405A79 mov dword ptr [ebp-0Ch],ecx
39:
40: delete []pc1;
00405A7C mov edx,dword ptr [ebp-4]
00405A7F mov dword ptr [ebp-1Ch],edx
00405A82 mov eax,dword ptr [ebp-1Ch]
00405A85 push eax
00405A86 call operator delete (00407e20)
00405A8B add esp,4
41: delete []pc2;
00405A8E mov ecx,dword ptr [ebp-8]
00405A91 mov dword ptr [ebp-20h],ecx
00405A94 mov edx,dword ptr [ebp-20h]
00405A97 push edx
00405A98 call operator delete (00407e20)
00405A9D add esp,4
42: delete []pc3; ;代码改为delete pc3; 或是delete [10]pc3; 反汇编代码均相同
00405AA0 mov eax,dword ptr [ebp-0Ch]
00405AA3 mov dword ptr [ebp-24h],eax
00405AA6 mov ecx,dword ptr [ebp-24h]
00405AA9 push ecx
00405AAA call operator delete (00407e20)
00405AAF add esp,4
在堆中动态分配存储单元, 每次分配操作所分配的单元之间总是有余量, (或者说分配的内存块之间的距离比申请的单元数要多一点, 比如至少0x48个字节, 再一次以16个字节递增),
释放空间时释放若干个, 跟踪代码执行, 发现并不仅仅是释放所分配的单元,而是连同附近的若干个存储单元加以释放。
char *pc1 = new char();
相当于:
char *pc1;
pc1 = (char *)malloc(1*sizeof(char));
char *pc2 = new char(10);
相当于:
char *pc2;
pc2 = (char *)malloc(1*sizeof(char));
if(pc2 != 0)
*pc2 = 10;
char *pc3 = new char[10];
相当于:
char *pc3;
pc3 = (char *)malloc(10*sizeof(char));
问题:在动态分配时可以指定分配存储单元的数量, 但是释放时却不能, 那如何进行释放? 根据所提供地址的附近的单元的内容?