1. 数据存放
bss 段:来存放没有初始化和初始化为0的全局变量,bss类型的全局变量只占用运行时的内存空间而不占用文件空间。
data段:用来存放初始化非0 的全局变量,data类型的全局变量既占用运行时的内存空间又占用文件空间。
rodata段:用来存放常量数据,rodata在只读的内存页面中是受保护的,任何试图对它的修改都会被及时发现,可以提高程序的稳定性。
代码段:用来存放代码(如函数)和部分整数常量
栈:用来存放临时变量和函数参数
堆:向系统申请的内存
堆中的函数:malloc 用来分配一块指定大小的内存
realloc 用来调整一块存在的内存
free 用来释放不再使用的内存
使用堆内存需要注意,malloc / free 要配对使用
2. 内存分配方式
(1):从静态存储区分配
(2):在栈上创建
(3)从堆上分配,亦称动态内存分配
3. 野指针
野指针的成因:(1)指针变量没有初始化(2)指针p被free或者delete之后,没有置为NULL ,让人误以为p是合法的指针。
4. 常见的内存错误及对策
(1)内存分配为成功,却使用了它 对策:在使用前检查指针是否为NULL
(2)内存分配虽然成功,但尚未初始化就引用它 对策:在创建时进行复制
(3)内存分配成功并初始化,但操作超出了内存的边界 对策:注意检查
(4)忘记释放内存,造成内存泄漏 对策:动态内存的申请与释放必须配对
(5)释放例内存却继续使用它
5. 段错误以及调试方法
段错误就是访问例错误的内存段
调试方法
(1)利用gdb逐步查找段错误
(2)分析core文件
(3)段错误时启动调试
(4)利用backtrace和objdump进行分析
6. 指针和数组的对比
数组要么在静态存储区被创建(全局数组),要么在栈上被创建。数组名对应着一块内存,它的地址与容量在生命周期内保持不变,只有数组的内容可以改变。
指针可以随时指向任意类型的内存块,它的特征是“可变”,所以常用指针来操作动态内存。指针远比数组灵活,但更危险。
7. 宏定义:#define
(1) 无参宏定义: #define 标识符 字符串
常对程序中反复使用的表达式进行宏定义
(2) 带参宏定义: #define 宏名(形参表) 字符串
带参宏定义中,形参不分配内存单元;在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。
8. 文件包含
#include “文件名” 或者 #include <文件名>
使用“”是首先在当前的源文件目录中查找,若未找到才到包含目录中去查找;使用 < >表示在包含文件目录中去查找,而不是在源文件目录去查找。
9. 条件编译
(1) #ifdef 标识符
程序段1
#else
程序段2
#endif
如果标识符已被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。
(2)#ifndef 标识符
程序段1
#else
程序段2
#endif
如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。
(3)#if 常量表达式
程序段1
#else
程序段2
#endif
如果常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译。
10. 结构体
(一)一般形式:
struct 结构体名
{
类型名1 成员名1;
类型名2成员名2;
... ...
类型名n成员名n;
} ;
(二)定义结构体类型的变量、指针变量和数组
1) .定义结构体类型时,同时定义该类型变量
struct [student]
{
char name [10];
char sex ;
int age;
float score ;
}stu 1, *ps , stu[5];
2) .先定义结构体类型时,再定义该类型变量
struct student
{
char name [10];
char sex ;
int age;
float score ;
};
struct student stu 1, *ps , stu[5];
3) .用typedef先给结构体类型命名,再用别名定义变量
typedef struct [student]
{
char name [10];
char sex ;
int age;
float score ;
}STU;
STU stu 1, *ps , stu[5];
(三)为结构体变量赋初值
struct [student]
{
char name [10];
char sex ;
int age;
float score ;
}stu [1] = {‘Li’,’F’,’22’,’90.5’};
(四)引用结构体变量中的成员
结构体变量名 . 成员名,如“stu1.name”
结构体指针变量 - > 成员名,如“ps- > name”
( * 结构体指针变量) . 成员名,如“(* ps).name”
结构体变量数组名 . 成员名,如“stu[0].name”