printf("0x%08x\n",&s1); //打印各静态变量的内存地址
printf("0x%08x\n",&s2);
printf("0x%08x\n\n",&s3);
return 0;
}
编译后的执行结果是:
0x0012ff78
0x0012ff7c
0x0012ff80
0x004068d0
0x004068d4
0x004068d8
0x004068dc
0x004068e0
0x004068e4
输 出的结果就是变量的内存地址。其中 v1,v2,v3 是本地变量,g1,g2,g3 是全局变量,
s1,s2,s3 是静态变量。你可以看到这些变量在内存是连 续分布的,但是本地变量和全局变
量分配的内存地址差了十万八千里,而全局变量和静态变量分配的内存是连续的。这是因为
本地变量和全局/静态变量是分配在不 同类型的内存区域中的结果。对于一个进程的内存空
间而言,可以在逻辑上分成 3 个部份:代码区,静态数据区和动态数据区。动态数据区一般
就是“堆栈”。“栈 (stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结
构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然 代码一样,
但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全
局变量和静态变量分配在静态数据区,本地变量分配在动态数 据区,即堆栈中。程序通过
堆栈的基地址和偏移量来访问本地变量。
├———————┤低端内存区域
│ …… │
├———————┤
│ 动态数据区 │
├———————┤
│ …… │
├———————┤
│ 代码区 │
├———————┤
│ 静态数据区 │
├———————┤
│ …… │
├———————┤高端内存区域
堆 栈是一个先进后出的数据结构,栈顶地址总是小于等于栈的基地址。我们可以先了解一
下函数调用的过程,以便对堆栈在程序中的作用有更深入的了解。不同的语言 有不同的函
数调用规定,这些因素有参数的压入规则和堆栈的平衡。windows API 的调用规则和 ANSI C
的函数调用规则是不一样的,前者由被调函 数调整堆栈,后者由调用者调整堆栈。两者通
评论0