工学1号馆

home

C程序的存储空间布局

By Wu Yudong on July 31, 2016

本文介绍C内存管理的基础概念和原理

正文段(Text):由CPU执行的机器指令部分,通常,正文段是可以共享的,所以即使是频繁执行的程序在存储器中也只有一个副本,正文段常常是只读的,防止程序由于意外而修改其指令。

初始化数据段(Data initialized):包含了程序中已经赋值的变量

未初始化数据段(BSS uninitialized):存放为初始化的变量

堆(Heap):堆是用户可以动态分配的一块内存,持续存在直到释放或者程序退出

栈(Stack):自动变量以及每次函数调用所需保存的信息都放在此段中。每次函数调用时,其返回地址以及调用者的环境信息都放在栈中。然后最近被调用的函数在栈上为其自动变量和临时变量分配存储空间。注意:递归函数每次调用自身时,就用一个新的栈帧。

内存布局

QQ截图20160731083236

本文地址:http://wuyudong.com/2016/07/31/2384.html,转载请注明源地址。

调用栈

例如:DrawSquare函数被main函数调用

void DrawSquare(int i)
{
    int start, end, ...    //其他局部变量
    DrawLine(start, end);
}

void DrawLine(int start, int end)
{
    //局部变量
    ...
}

具体过程如下图:

刚开始时时候,函数还没调用,栈中没有数据,栈是从高地址向低地址延伸的。

QQ截图20160731103227

随着函数的调用,首先是DrawSquare函数被调用,进栈后对应一个栈帧,接着是DrawLine函数被调用,进栈后对应一个栈帧,如图:

QQ截图20160731103625

随着函数的执行,栈帧中的函数以及局部变量相继出栈,回到起始阶段

C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)。

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)