C语言之旅(6)内存空间的管理

来源:互联网 发布:命运 定数 知乎 编辑:程序博客网 时间:2024/05/31 06:22

本文参考:http://blog.csdn.net/wealoong/article/details/8686353

C语言编译的程序占用的内存分为5个部分:1.栈区;2.堆区;3.全局区(静态区);4.文字常量区;5.程序代码区。

1.栈区:程序运行的时候由编译器自动分配的,例如函数中的局部变量int a;等等。程序结束的时候由编译器自动的释放。不需要程序员进行管理。

2.堆区:这块区域是指程序员在程序中自行根据需求向内存申请空间的地方。在C语言中用malloc进行内存的申请,这个时候申请的空间,除非程序员通过free函数释放掉,否则这块空间在整个程序结束前一直存在,知道程序运行结束,将会被操作系统回收。

3.全局区(静态区):编译器编译的时候分配内存,全局变量和静态变量(static)存放的区域,生命周期将是整个程序,当程序结束的时候由操作系统进行回收释放。

4.文字常量区:常量字符串存放的地方,生命周期是整个程序,当程序结束的时候由操作系统进行回收释放。什么是字符常量呢?其实就是例如:"abcdefs"。这样的字符串。

5.程序代码区:这里面存放编译链接生成的可执行的二进制代码。



堆和栈的区别:

1.管理方式不同;2.空间大小不同;3.能否产生碎片不同;4.生长方向不同;5分配方式不同;分配效率不同。

1.管理方式不同:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生内存泄漏(忘记释放)。

2.空间大小:;一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如在VC6

下面,默认栈空间大小是1M,当然,这个值可以修改。

3.碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使用效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远不可能有一个内存块从栈中间弹出来,在他弹出来之前,在他上面的后劲的栈内容已经被弹出来。

4.生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长的。(因为对于栈来说,栈顶指针是在高地址的,因为段地址偏移地址的存在,对于8086CPU一个栈最大是64k。其余架构可能不是这个数字,道理一样的。所以栈的大小是确定的。详情可以看一下汇编书籍。)

5.分配方式:堆都是动态分配的,没有静态分配的堆。栈 有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配,动态分配是由malloc函数分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放的,无需我们手工实现。

6.分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址(SS:栈段 sp:栈顶指针),压栈出栈都有专门的指令执行(push和pop),这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法在堆内存中搜索可用的足够大小的空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低的多。



阅读全文
0 0
原创粉丝点击