【C语言复习(二十四)】C语言程序内存结构总结

来源:互联网 发布:贵阳大数据会议 编辑:程序博客网 时间:2024/06/09 20:03

详细资料请参考:

C语言复习(二十一)】C语言程序的存储区域

C语言复习(二十二)】C语言程序的内存段

C语言复习(二十三)】C语言程序中段的使用

 

根据前三篇文章的介绍,这里做一个简单的总结

1、三国天下

        一个C语言程序在运行时,内存结构分为:全局静态区、动态区;动态区又包括:堆区、栈区;


全局静态区:程序运行过程中始终存在,运行结束后由操作系统释放,全局静态区里的大部分内存段在编译链接后产生,只有一个例外,是在程序初始化时开辟;


动态区:

        程序运行过程中,由程序动态分配和释放的区域;

        堆区:使用malloc函数申请的空间位于此内存区,使用后需要调用free函数释放,否则发生内存泄露等问题;

        栈区:程序函数内部中使用的变量、函数的参数、函数的返回值将存储在此内存区,由编译器自动分配和释放;


全局静态区:

        全局静态区又分为:只读数据区、读写数据区

        只读数据区又分为:代码段、只读数据段

        只读数据段:只读全局量、只读局部量、程序中使用的常量

        读写数据区:已初始化数据段、未初始化数据段

        已初始化数据段:已初始化全局(静态)变量、已初始化局部静态变量


2、程序中的栈区

        栈中保存了一个函数调用所需的所有维护信息
        函数参数、函数返回值
        局部变量
        函数调用上下文
如图:

        在整个程序运行期间,首先进入main函数,然后调用其他函数时,程序的运行流程转出,并依次开辟如图的栈空间,因为调用完函数后还需返回原位置继续执行main函数,因此会记录返回地址,ebp为基址指针,它保存的值是上一个ebp的值,整个被调用的函数所需栈空间分配完成后,栈顶指针esp会指向栈顶,被调用函数运行结束后,栈顶指针会返回刚刚调用函数的流程转出处,这就依赖于ebp指针向前读取一个字节,然后赋给esp,这样栈顶就回到流程转出处了,接着ebp读取old ebp的值,返回上一个函数的ebp位置,这样一个函数调用流程结束。

 

3、程序中的堆

        栈上的数据在函数调用返回后就会被释放掉,无法传递到函数外部,如:函数局部变量,因此才有了堆

        堆是程序运行时一块巨大的内存空间,可由程序自由使用;
        堆中被程序申请使用的内存在程序主动释放前将一直有效;

        堆空间的使用需要申请,使用完后应该及时释放;


4、系统对堆空间的管理方式

        基本的管理方式大概有:空闲链表法,位图法,对象池法等等

        这里仅仅简单介绍一下空闲链表法:

 

        比如当前想要申请一个4直接的空间,然后系统会根据链表去查询哪一个空间比较符合4字节,这里查找到了一个5字节的空间,然后系统就会把这个空间的起始地址返回给程序,这就是为什么有时候申请的堆空间比我们想要的大一点的原因。

 

5、静态存储区

        程序静态存储区随着程序的运行而分配空间,直到程序运行结束;

        在程序的编译期静态存储区的大小就已经确定;

        程序的静态存储区主要用于保存程序中的全局变量和静态变量;

        与堆和栈不同,静态存储区的信息最终会保存到可执行程序中;

 

6、小结

        堆、栈和静态存储区是C语言程序涉及的三个基本存储区;

        栈区主要用于函数调用的使用;

        堆区主要是用于内存的动态申请和归还;

        静态存储区用于保存全局变量和静态变量;

0 0
原创粉丝点击