数据存放位置
未初始化的全局变量 .bss段
存放没有初始化或初始化为0的全局变量
不占文件空间,只占运行内存
初始化过的全局变量 .data段
初始化非零的全局变量
既占文件空间,又占运行内存。
常量数据 .rodata段
- 多个进程间共享
- 删除重复的字符串
- 一部分嵌入式系统中,rodata 放在 ROM 或 NOR Flash中,运行时直接加载到RAM内存中
- 在嵌入式中,可以用XIP(就地执行),无需加载到RAM内存中
- 常量不可修改
代码 .text段
存放程序执行代码,内存区域属于只读。也有可能包含一些只读的常数变量,例如字符串常量等。
栈
管理函数调用时的临时变量,存放在栈中的数据只在当前函数和下一层函数中有效,一旦函数返回了,数据就自动释放了。
堆
- malloc 用来分配一块指定大小的内存
- realloc 用来调整/重分配一块存在的内存
- free 释放内存
1.malloc/free 配对使用
2.每个区间有四个属性,rwx三个属性和p/s(表示是否为共享内存)
内存空间 | 属性 |
---|---|
.bss段 | (r-wp) |
.data段 | (r-wp) |
.rodata段 | (r-p) |
.text段 | (r-xp) |
没有文件名的内存空间 | 用mmap映射匿名空间 |
文件名为[stack] | 栈 |
文件名为[heap] | 堆 |
内存分配方式
- 从静态存储区分配,在编译时分配好,有全局变量,static变量等。
- 在栈上创建,执行函数时,局部变量在栈上创建,执行结束后自动释放。
- 从堆上分配,动态内存分配,如用malloc或new申请所需的内存,用free或delete释放内存。
野指针
- 指针没有被初始化,就使用。
- 指针被free或delete后,没有置位NULL,容易误用。
常见错误
- 内存未分配成功,参数指针判断用assert(p!=NULL),用malloc或new申请内存的用if(p!=NULL)
- 内存没有初始化
- 操作越过内存边界
- 忘记释放内存,导致内存泄漏
- 释放了内存还继续使用
段错误
访问了错误的内存段
用gdb调试
编译时 加上 -g -rdynamic 参数编译,生成带有调试信息的可执行程序
分析core文件
ulimit -c 1000
gdb ./a.out core