很多朋友对编译器和系统对变量如何分配内存不是很清楚,也很容易搞糊涂,我们下面 就以一个小程序为例看看编译器和系统是如何为变量分配内存的.
注意:我的编译环境为VC++6.0. 系统平台为: windows XP 不同的编译环境和操作系统可能有所不同.
#include < iostream>
using namespace std;
|
0012FF7C |
5 |
|
0012FF78 |
4 |
|
0012FF74 |
3 |
|
0012FF70 |
2 |
|
0012FF6C |
1 |
|
0012FF68 |
10 |
|
0012FF64 |
9 |
|
0012FF60 |
8 |
|
0012FF5C |
7 |
|
0012FF58 |
6 |
a[4]
a[3]
a[2]
a[1]
ß a[0]
b[4]
b[3]
b[2]
b[1]
ß b[0]
根据上面的图表我们可以看出:数据在内存中的 存储情况。即编译器和系统在为变量分配是从高地址开始分配的.
分析代码:
int a[5] = { 1,2,3,4,5} ;
我们定义了一个数组a,那么此时系统和编译器便从栈地址区找出一块空闲内存分配给数组a.然后数组a便在这块内存中 从高地址开始存储,即a[4]--->a[0]
int b[5] = { 6,7,8,9,10} ;
我们又定义了一个数组b,那么系统和编译器以同样的方法对待b,不过这次是接着a的结束地址往下开始分配(由高往 低).
最后的结果便是上面的图表所列的情况,从上面表中我们可以看出b[5]便是a[0]单元,b[6]是a[1]单元.
所以输出结果便是2了.
也许有些朋友对这个在理解上有些困难,我们再来看一个简单的:
#include < iostream>
using namespace std;
int main()
{
int a = 2;
int b = 3;
int * p = & b;
cout << * p << endl;
cout << * (++ p) << endl;
return 0;
}
输出结果:
3
2
我们可以使用:
cout << &a << endl;
cout << &b << endl;
来查看a,b在内存中的地址情况:
0012FF7C
0012FF78
可以看出a的地址高于b的地址.且他们之间差了4个字节,这是因为a占4个字节.
这样我们应该就可以理解为什么输出结果为3 2了。p开始指向变量b,即在变量p的内存空间中存有b的地址。我们输出*p,即输出b的值为3.而后我们输出*(++p)即现对p里面的内容+1,然后 输出*p.
这里有一点提醒的是: +1操作并不是总是+1,它有它自己的单位,在这里它的单位为4个字节,即一个int型的大小.所以在p+1后就指向了变量a.所以输出结果就为2了.
好的,问题解决了,但是新的问题又来 了。
那么全局变量,以及函数中的参数也是 如此吗?
-
- #include <iostream>
- using namespace std;
- int x;
- int y;
- void function( int x, int y)
- {
- y = 1;
- x = 2;
- int kk;
- int yy;
- printf( "x = %d,y = %d/n" ,x,y);
- }
- int main()
- {
- x = 1;
- y = 2;
- function(x,y);
- int z;
- int t;
- printf( "x = %d,y = %d/n" ,x,y);
- }
我们可以对上面的一段代码加上断点,对其进行调试然后查看各个变量的地址进行比较就可以看出。全局变量和函数参数在 内存中的存储是由低地值到高地址的.这又是什么原因呢?
我们需要清楚的是:内存分为不同的区域用于不同的作用.
全局变量是放在全局区里的。函数的参数是放在堆区中的.对于这点可能有些朋友会不明白了,函数参数为什么会放到堆区 呢?这是因为我们的函数是在程序运行中进行动态的调用的.在函数的编译阶段根本无法确定他会调用几次,会需要多少内存.即使可以确定那时候就为变量分配好 内存着实也是一种浪费。所以编译器为函数参数选择动态的分配..即在每次调用函数时才为它动态的进行分配空间.
而那为什么这两个区域的变量在内存中的存储就是顺序的呢?
我想这个问题就是栈机制的影响吧.函数内部定义的非动态分配的,非静态变量都是放在栈区的.我们大家都清楚栈有着后 进先出的特性.并且栈区不但要保存部分变量,还有保存函数的入口地址,断点地址,参数等.这种栈的机制对函数调用,中断都有着很重要的作用.
而在全局区,堆区中没有这种机制,也无需这种机制,也就顺序分配了.
本文通过实例代码解析编译器和Windows环境下内存分配的方式,从栈、堆到全局变量的存储顺序,阐述内存管理的原理。

被折叠的 条评论
为什么被折叠?



