内存管理分析

来源:互联网 发布:html5实例源码 编辑:程序博客网 时间:2024/05/05 03:35

题目:分析下面代码的运行结果。

#include <stdio.h>char *GetMemory(){char a[] = "hello,world";/*char *a = "hello,world";//这样声明的话有效 */return a;}int main(int argc, char *argv[]){printf( "%s\n", GetMemory() );getchar();return 0;}

运行结果是:输出乱码或者程序崩溃。原因是a指向的临时内存地址在函数调用完了之后,对应的空间已经释放,再去访问的话,是非法的。

分析:在VS2012下面, 程序执行后出现乱码,因为函数返回时,函数内的栈空间已被清除。
注意:对于字符串"hello,world"而言,他所在的空间不是栈,而是堆,所以一开始我觉得本程序执行的结果是可以正常输出的,但是,实际结果并非如此。经反汇编发现,函数GetMemory的操作不是使得a指向堆里面的字符串,而是把堆里面的字符串拷贝一份到栈里面,所以函数调用完之后,返回的地址是栈内的地址,而函数完了之后栈会自动清除,所以会出现乱码。但是如果a的声明是指针(int *a),而不是数组,那么可以正常输出,因为函数内部的a指向的是堆里面的字符串,所以返回的地址有效。

反汇编代码如下:

;;两个不同的版本;;数组;;这个是har a[] = "hello,world";的反汇编代码char a[] = "hello,world";;下面的这一段是实现堆内字符串拷贝到栈内的00AC1AE8  mov         eax,dword ptr ds:[00AC5858h]  00AC1AED  mov         dword ptr [a],eax  00AC1AF0  mov         ecx,dword ptr ds:[0AC585Ch]  00AC1AF6  mov         dword ptr [ebp-10h],ecx  00AC1AF9  mov         edx,dword ptr ds:[0AC5860h]  00AC1AFF  mov         dword ptr [ebp-0Ch],edx  ;;指针;这个是char *a = "hello,world";的反汇编代码char *a = "hello,world";01001ADE  mov         dword ptr [a],1005858h