预览加载中,请您耐心等待几秒...
1/3
2/3
3/3

在线预览结束,喜欢就下载吧,查找使用更方便

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

#include<iostream>usingnamespacestd;intnG=1;voidFun(){staticgg=2;intlocal=gg;}intmain(){----------------1staticinta=3;intb=nG;intc=a;Fun();staticoo=4;c=oo;return0;} 我们所关心的是这些变量如nGgga等等在内存中的分布如何?它们都紧挨着放在一块?还是各有个的存储块为了解决上述问题,首先提出第一个问题?Fun()中的局部静态变量gg在多次调用Fun()后(比如2次)的值是多少?你肯定毫无犹豫地答到:2我如果问为什么?你可能毫无犹豫的答道:局部静态变量gg只是在第一次进入函数时被初始化。变量gg真的是在第一次进入函数时才被初始化的吗??!!我们可以单步调试跟踪一下,你会发现调试时会直接跳过staticgg=2;这一行。因此我说变量gg在进入Fun函数之前就已经存在了,你信吗?我们可以将断点插在1处,调试Alt+8进入底层的汇编代码12:staticinta=3;//对应着main函数中的声明,此时EBP=0x0012FFC013:intb=nG;00404BB8moveax,[nG(00476f90)]//这两句给b赋值,可以发现全局变量nG的地址是:0x00476F9000404BBDmovdwordptr[ebp-4],eax//b的地址是0x0012FFBC14:intc=a;00404BC0movecx,dwordptr[nG+8(00476f98)]//这两句是给a赋值,可以发现局部静态变量a的地址是00404BC6movdwordptr[ebp-8],ecx//0x00476F98,c的地址是:0x0012FFB815:Fun();00404BC9call@ILT+790(Fun)(0040131b)--------看下面Fun的汇编代码16:staticoo=4;17:c=oo;00404BCEmovedx,dwordptr[nG+0Ch(00476f9c)]//局部静态变量oo的地址是0x00476F9c00404BD4movdwordptr[ebp-8],edx18:return0;00404BD7xoreax,eax19:}Fun的汇编代码:7:staticgg=2;8:intlocal=gg;004051B8moveax,[nG+4(00476f94)]//这两句在给local赋值,可以发现局部静态变量gg的地址是004051BDmov[nG(00476f90)],eax0x00476F949:}由上述可以发现变量nGggaoo它们几个的内存地址很相近0x00476F90:-----------------nG的地址0x00476F94:-----------------gg的地址0x00476F98:-----------------a的地址0x00476F9C:----------------oo的地址我们可以发现这些全局变量和静态变量的内存地址,是在一块的。总结:我们通常都说main函数是程序的入口点,所以就很容易造成一种误解。认为程序一运行就进入了main,这是不对的。既然main是函数,是函数就得被调用了才能执行。那么是谁调用了main函数呢?通过调用堆栈我们发现,在main函数前还有一个函数:mainCRTStartup()。这个函数通常被称为启动代码,由他对程序在进入main函数之前进行初始化(如加载动态链接库分配资源等等),毕竟程序的正常运行不是仅仅依靠小小的main就行的。当然初始化过程中包含对全局变量和静态变量的内存分配。这里的全局变量可能好理解,但是静态变量就有点难理解了。比如Fun中的gg他是一个局部静态变量啊为什么会在进入main函数之前就被初始化啦。这就是静态变量的特性,这就是通常我们为什么说静态变量的生命周期,和整个程序的生命周期是一样的。下面简要的说一下本程序的运行流程:首先由启动代码完成一些必要资源的加载,和全局变量、静态变量(你程序中的所有静态变量,包括局部的)初始化,分配内存单元。进入main函数,首先进行的操作是在栈上分配一块内存单元,用来分配函数中的局部变量(除了静态变量)和参数的压栈以及函数地址的压栈。也就是说上面的main中的局部非静态变量b和c就分配在此内存块中,它会在main函数返回后释放。同理在进入Fun函数时,首先也会在栈上分配一块内存单元,用来分配Fun函数中的局部变量(除了静态变量)和参数的压栈以及函数地址的压栈。比如Fun中的local就分配在此段内存块中,它会在Fun函数返回以后被释放。最后return0返回,释放分给main函数的内存块,main函数结束以后由mainCRTStartu