文章目录
1、内存分区
五大内存分区,及存储数据如下:
内存区域 | 存放数据类型 |
---|---|
BSS | 程序中还未初始化的全局变量,静态变量 |
数据段 | 初始化后的全局变量,静态变量 |
代码段 | 程序代码和常量,一般只允许读 |
堆 | 动态分配的内存段(maloc/new,free/delete) |
栈 | 临时创建的局部变量,函数形参,数组函数调用时,参数被压入栈 |
内存分配方式:
1、静态存储区
2、栈
3、动态存储区:堆
2、各数据类型在32位/64位下的字节长度
数据类型 | 32位下 | 64位下 |
---|---|---|
char | 1 | 1 |
float | 4 | 4 |
int | 4 | 4 |
short | 2 | 2 |
double | 8 | 8 |
long | 4 | 8 |
void*(指针) | 4 | 8 |
3、malloc/free 和 new/delete
delete 和delete[]区别
delete:调用一次析构函数,释放单个指针指向的内存,对多维数组使用,可能会产生内存泄露
delete[] :对每个成员使用一次析构函数,释放数组指针指向的内存
malloc/free 和 new/delete 的区别
malloc/free | new/delete | |
---|---|---|
类别 | 函数 | 操作符 |
参数 | 手动传入空间大小 | 空间大小 |
返回类型 | void*(使用时需要强转) | 对象类型指针(无需转换) |
调用结果 | 申请相应大小空间 | 申请空间并创建新对象 |
调用失败 | 返回null指针,使用时需要判空 | 抛出异常(bac_alloc) |
重载 | 不能 | 可以 |
分配内存 | 堆 | 自由存储区(new申请的空间,不等于堆) |
4、内存错误及解决方法
错误原因 | 解决方法 |
---|---|
内存未分配成功,就使用 | 使用malloc/new 分配内存记得判断返回指针是否为null |
内存分配成功但是没有初始化 | 申请结束就初始化 |
越界访问 | 循环的时候注意条件,注意是否越界 |
忘记释放内存 | malloc/free ,new/delete配对使用 |
释放内存后依旧使用它 1)野指针 2)函数返回的是否是栈中的指针或者引用 3)对象调用过于复杂,不清楚是否释放 | delete/free 使用后将指针设为null,避免野指针 |
内存泄露的原因
1、构造函数和析构函数中没有匹配调用malloc/free,new/delete。
2、没有正确的清除嵌套的对象指针
3、释放对象数组在delete时没有用方括号
4、指向对象的指针数组不等于对象数组,对象数组只要delete []p,指针数组需要通过循环释放掉每个对象,再释放指针
5、缺少拷贝构造函数/重载赋值运算符,这样可能会造成同一个内存块的两次释放
6、基类的析构函数不是虚函数,基类指针指向子类时,子类的析构函数不会被调用,资源泄露
7、使用指向没有初始化或者free/delete之后的空间的指针,或者指针操作超越了变量的作用范围