一、数据存放区
1、bss段
未初始化或者初始化为0的全局变量,存放在bss段。
全局变量只占运行时的内存空间,不占用文件空间;在整个程序运行期间,bss数据一直存在。
2、data段
初始化为非0的全局变量,存放在data段;
全局变量不仅占用运行时的内存空间,而且还占用文件空间;在整个程序运行期间,data数据一直存在。
3、rodata段
常量数据一般存放在rodata段。
多个进程间共享rodata段数据,大大提高空间利用率,甚至不占用RAM空间。
rodata段数据受只读内存页的保护,任何更改会被及时发现。
字符串会被编译到rodata段内,其他数据需要加const关键字之后,也可以被放到rodata段中。
4、text段
存放代码(函数等)和部分整数常量。
5、stack栈
栈用来存放临时变量和函数参数。
6、heap堆
相关的函数:malloc、realloc、free。
二、内存错误及对策
1、使用指针前,判断内存是否分配成功。
p是函数参数时,函数入口处使用assert(NULL!=p);
p是malloc或者kmalloc申请的,需要使用if(NULL == p)或者if(NULL!=p)进行防错处理。
2、内存申请成功之后记得初始化。
创建数组时,莫忘初始化。
3、malloc和free函数成对出现。
4、free内存之后,将指针置为NULL。
三、段错误及调试方法
段错误(Segmentation fault)
1、gdb调试
[zc@centos] $ gcc -g -rdynamic d.c
[zc@centos] $ gdb ./a.out
2、core文件
[zc@centos] $ ulimit -c #查看core文件的限制大小
[zc@centos] $ ulimit -c 1000 #修改core文件的限制大小,使之生成core文件
[zc@centos] $ ./a.out #会产生core文件
[zc@centos] $ gdb ./a.out core
3、直接运行
[zc@centos] $ gcc -g -rdynamic d.c
[zc@centos] $ ./a.out
(gdb):bt
4、backtrace和objdump
[zc@centos] $ gcc -g -rdynamic d.c
[zc@centos] $ ./a.out
[zc@centos] $ objdump -d a.out