内存管理分析

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

#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  


原文地址:https://www.cnblogs.com/arbboter/p/4225224.html