C++内存模型&空指针、野指针、函数指针和回调函数
C++内存模型&空指针、野指针、函数指针和回调函数
C++内存模型
栈与堆的区别:
1.管理方式不同
栈是系统自动管理的,在超出作用域后,将自动被释放
堆是手动释放,若程序中不释放,程序结束后将由操作系统回收
2.空间大小不同
堆的大小受限于物理内存范围
栈小的可怜,一般为8M(可通过更改系统配置来增加栈的大小)
3.分配方式不同
堆是动态分配
栈既支持动态分配也支持静态分配
4.分配效率不同
栈是系统中提供的数据结构
堆是C++函数库提供(链表)
5.是否产生碎片
栈:不会产生碎片
堆:由于频繁分配和释放,会造成内存空间的不连续,产生碎片
6.增长方向不同
栈向下增长 降序分配内存地址
堆向上增长 升序分配内存地址
指针
1.空指针
在C++中讲指针初始化为 **0** 和 **NULL** 都代表空指针
⭕在C++中添加的nullptr可以保证在任何情况下都代表空指针(建议使用)
int *p=0;
int *p=NULL;
int *p=nullptr;
❗使用空指针的后果
- 对空指针解引用,程序会崩溃
int *p=NULL;
cout <<"&p="<<&p<<endl; //对空指针解引用,程序会崩溃
2.对空指针使用delete运算符,系统会忽略该操作,程序不会崩溃
int *p=NULL;
delete p; //对空指针使用delete运算符,到这里不会报错
cout <<"&p="<<&p<<endl; //对空指针解引用,程序会崩溃
❓为什么空指针访问会出现异常
空指针是程序**无论何时**都没有物理存储器与之对应的地址,而为了确保“***无论何时”***这个条件,人们定义了空指针的****分区(0x00000000~0x0000ffff)
2.野指针
指针指向的不是一个有效(合法)的内存地址
❗出现野指针的情况(三种)
1.指针在定义时未初始化,其值不确定
2.指向堆分配的内存被释放时,指针指向的地址无效
3.指针指向的变量已超越了变量作用域
针对的解决方法
1.将指针初始化为nullptr
2.堆内存释放后将指针置为nullptr
3.函数不返回局部变量的地址
3.函数指针和回调函数
⭕使用函数指针的3个步骤
1.声明函数指针
2.函数指针指向函数地址(在C++中,函数名就是函数地址)
3.通过函数指针调用函数
/* 使用函数指针步骤
1.定义函数指针
int func(int a,std::string b)——>int (*pfunc)(int,std::string)
2.函数指针指向函数的地址(在C++中,函数名就是函数的地址)
pfunc=func;
3.通过函数指针调用函数
C++语法: C语言语法:
pfunc(a,b) (*pfunc)(a,b)
*/