首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

变量名是怎么访问内存地址的

2012-05-06 
变量名是如何访问内存地址的如int a 10在声明变量的时候,是不是也可以理解为int * a new int*a 10

变量名是如何访问内存地址的
如int a = 10;在声明变量的时候,是不是也可以理解为int * a = new int;*a = 10;呢?
还有在变量名生命期结束的时候,它是如何销毁的,只是通过出栈吗,而不修改该变量内存里的值,还有是像类一样调用析构函数?

[解决办法]
int a = 10;在声明变量的时候,是不是也可以理解为int * a = new int;*a = 10;其实不能这样理解,过程差不多,但是你要知道int a的话,a存放在栈里,*a = new int后,这个a 就在堆空间里了。变量周期结束后被出栈后就结束了
[解决办法]
首先,编译后的程序里没有变量名
所有的变量名,编译后在可执行程序里都是单纯的内存地址

其次,变量可以放在栈中也可以放在堆中
放在栈中的变量就是单纯的进栈出栈,里面的地址是连续的,不需要申请也不需要释放,移动栈顶指针就OK
放在堆中的地址就需要申请和释放
至于析构函数,那是被调用的函数,编译后和普通函数没有区别,只是编译器在编译的时候自动在变量结束时在内存操作(释放堆或出栈)之前添加上析构函数的调用而已——话说这是C语言版,哪来的析构函数?
[解决办法]
举个例子。我有一个函数,假设ebp(栈底)是0xbfffefd8,esp(栈顶)是0xbfffefc8。函数中定义的变量就在ebp+4,ebp+8这些位置。

函数运行阶段,访问函数内的变量,会通过ebp+4,ebp+8来进行。

当函数调用结束,需要返回的时候,会执行leave这条指令。leave的作用之一就是mov $ebp, $esp,用c表达就是esp = ebp。

ebp是栈底,始终不变。本来esp=0xbfffefc8,经过这一步后,esp=0xbfffefd8。当栈顶指向栈底的时候,也就是说栈的空间已经不存在了,在那些内存上的变量还没有改写过,只是你已经失去了对这些变量的控制。
[解决办法]
如果是局部变量,运行时生成,变量名本省就对应着一段内存空间,具体如何实现等大牛详解

如何销毁,直接销毁了此段 stack frame. 具体可以看一下 深入理解计算机系统 第六章
[解决办法]
如果你是把它定义在函数里:
编译器在见到 int a = 10 后写代码指定以当前栈指针的某个偏移量位置开始保留一个 4 字节空间,并将 10 作为一个 int 数存入该空间中。以后的代码里对 a 的访问就以对栈指针+该偏移量所指空间来代替了。

如果是定义为全局变量:
编译器在堆中留出 4 个字节,将 10 作为一个 int 数存入该空间中。以后的代码里对 a 的访问就以对该空间的访问来代替。
[解决办法]

探讨

引用:

举个例子。我有一个函数,假设ebp(栈底)是0xbfffefd8,esp(栈顶)是0xbfffefc8。函数中定义的变量就在ebp+4,ebp+8这些位置。

函数运行阶段,访问函数内的变量,会通过ebp+4,ebp+8来进行。

当函数调用结束,需要返回的时候,会执行leave这条指令。leave的作用之一就是mov $ebp, $esp,用c表达就是e……

[解决办法]
定义的变量加载到内存时放在哪个位置,占用多少的空间这些都是有编译器来决定的。
[解决办法]
有时根本用不着内存
[解决办法]
是,有时还会在机器码中消失
[解决办法]
优化之后确实不一定保存在内存里。
[解决办法]
对C语言来说,变量名一般只存在于编译期。到运行期变量都对应内存地址了。

热点排行