zoukankan      html  css  js  c++  java
  • 内存管理分析

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

    #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  


  • 相关阅读:
    docker 安装 nexus3 初始密码不再是admin123
    eclipse中Tomcat修改项目名称
    WAMP3.1.3自定义根目录
    git学习笔记
    小米和MAC触摸板手势汇总
    IDEA快捷键汇总
    servelet 实现Post接口访问
    LeetCode:Jump Game II
    LeetCode:Trapping Rain Water
    LeetCode: Container With Most Water
  • 原文地址:https://www.cnblogs.com/arbboter/p/4225224.html
Copyright © 2011-2022 走看看