C与内存
段:
在UNIX中段表示一个二进制文件的相关的内容块。
而在Inter x86内存模型中,段表示一种设计结果。地址空间并不是一个整体而是分成一些64K大小的区域,称之为段。
对于一个a.out的可执行文件编译器和链接器向其中写入了一些东西:
BSS段,数据段,文本段。
BSS段:
通常用来存放程序中未初始化的全局变量的一块内存区域,属于静态内存分配。
data段:
数据段通常是指用来存放程序中已经初始化的全局变量的一块内存区域,数据段属于静态内存分配。
TEXT段:
代码段通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
rodata段:
存放C中的字符串和#define定义的常量。
heap段:
堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可以动态的扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态的添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆栈中被提剔除(堆被缩减)还有一种调整堆的方法参见下面的内容。
stack段:
用户存放程序临时创建的局部变量,通俗来说就是函数{}中定义的变量(但是不包括static声明的变量,static意味着在数据段中存放变量,枚举类型同样不在其中,考虑内存对齐可知不论枚举多少个元素,一个枚举始终只占一个整形)除此之外,在函数被调用时,其参数也会被压入发起进程调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈由先进先出的特点,所以方便用来保存与恢复调用现场,所以我们可以把堆栈看成是一个寄存交换临时数据的内存区。
常量段:
常量段一般包含编译器产生的数据(与只读段包韩用户定义的只读数据不同)。比如说有一个加法语句产生的结果,编译期间算出的结果就保存在常量段中。
一般来说,一个程序本质上都是由BSS段,data段,TEXT段组成的
程序运行时所包含的数据结构:
堆栈段,过程活动记录等
内存:
数据段和堆:
像堆栈段能根据需要自动增长一样,数据段也包含了一个对象,用于完成这项工作就是堆。
堆内存的回收不必与它所分配的顺序一致,所以无序的Malloc与Free最终都会产生堆碎片。
堆的末端由一个称为break的指针来标识。当需要更大的内存时可以调用brk或sbrk函数移动break指针来扩大堆的大小。
内存泄漏:
内存经常出现两种错误:
1.释放或改写仍然在使用的内存(称为“内存损坏”)。
2.未释放不再使用的内存(称为“内存泄漏”)。
所以为了避免这种问题,每次在调用malloc函数分配内存时,注意在以后要调用相应的free来释放它。
段错误:
通常导致段错误的几个直接原因:
1.解除引用一个包含非法值的指针。
2.解除引用一个空指针。
3.在没有权限时向一个只读的文本写东西等越界行为
4.用完了堆栈或堆空间
5.在指针没有被初始化时就对指针进行使用
6.对一个已经释放的指针进行解除引用操作
图片
原文地址:http://blog.csdn.net/zmrlinux/article/details/45228397