内存分类
- 栈区、堆区、静态区、代码段
- 栈区 :用来存储局部变量、函数的形式参数(存放临时变量)
- 堆区 :动态内存分配
- 静态区 :存放静态变量、全局变量(程序结束时,才被销毁)
- 代码段 :存放函数体(类成员函数和全局函数)的二进制代码
int globalvar = 10; //globalvar 存储于静态区(数据段) static int stglobalvar = 10; //stglobalvar 存储于静态区 int main() { static int stcavar = 10; //stcavar 存储于静态区 int locavar = 10; //locavar 局部变量,存储于栈 int num1[10] = { 1,2,3,4 }; //num1数组存储于栈 char char2[] = "abcd"; //char2 存储于栈; *char2 存储于栈 const char* pchar3 = "abcd"; //pchar3 局部变量指针存储于栈中,*pchar3 存储于代码段中(常量区) int* ptr = (int*)malloc(sizeof(int) * 4); //ptr 局部变量指针存储于栈中; *ptr开辟的空间,存储于堆中 free(ptr); }
内存泄漏
- 什么是内存泄漏:因为某种原因导致程序未能释放不再使用的内存。
- 内存泄漏不是指物理上的内存消失,而是指失去了对某段内存的控制权(指针丢失)
- C++语法兼容C语言,所以C语言的malloc和realloc等都可以使用。
- C++语法还有新的方法可以动态申请内存空间——new和delete
- 注意:malloc开辟的空间只能free,new开辟的空间只能delete。
int main()
{
int* ptr1 = (int*)malloc(sizeof(int) * 4);
int* ptr2 = new int[10];
//开辟多个空间时,使用中括号
free(ptr1);
delete[] ptr2;
int* ptr3 = (int*)malloc(sizeof(int));
int* ptr4 = new int;
//开辟单个空间时
free(ptr3);
delete ptr4;
}
malloc和new的区别
- malloc和new在申请基本类型的空间时,都是一样的,没有区别。
- 【C++内存管理】区别:
- new在申请自定义类型时,会开辟空间,并调用构造函数进行初始化。
- malloc只是开辟空间,而不会进行初始化。
- delete是先析构函数清理,再释放空间。
- free只是释放空间。
- malloc开辟空间失败后返回NULL,而new开辟空间失败会抛异常。
- 32位系统下,new和malloc最多能申请2G内存,想申请更大内存可以换成64位。
struct List
{
List* _pre;
List* _next;
int _val;
List(int val = 0)//构造函数
:_pre(nullptr)
,_next(nullptr)
,_val(val)
{}
};
int main()
{
struct List* n1 = (struct List*)malloc(sizeof(struct List));
List* n2 = new List;
}
文章图片
operator new和operator delete函数
- new和delete是系统提供的操作符,而operator new和 operator delete是系统提供的全局函数
- 操作符new的底层是通过调用operator new来申请空间的。
- 操作符delete的底层是通过调用 operator delete来释放空间的。
- new 相当于 operator new + 构造函数
- delete相当于 析构函数 + operator delete
- operator new 相当于 malloc + 失败抛异常机制
- operator delete 相当于 free
- operator new 和 operator delete 在功能上和 malloc 和free 相同
- 都只是开辟空间而不会调用构造函数进行初始化。
文章图片
- 主要区别是:当开辟空间失败后,处理方法不同。
- operator new 失败后是抛异常
- malloc 失败后是返回 NULL。
- 当 try 中运行出现异常后,会立马跳转到 catch 中。
int main()
{
struct List* n1 = (struct List*)malloc(0x7fffffff);
if (n1 == NULL) //malloc失败返回 NULL
{
cout << "malloc 失败" << endl;
}try//尝试运行下列代码
{
List* n3 = (struct List*)operator new(0x7fffffff);
}
catch (const std::exception&e)//try运行失败后,捕获异常
{
cout << e.what() << endl;
}
}
文章图片
定位new(初始化已开辟的空间)
- 定位new是用来在已经开辟了的空间中,通过调用构造函数来对其进行初始化。
int main()
{
List* n1 = (List*)malloc(sizeof(List));
//开辟空间,但未初始化
new(n1)List;
//定位new 调用构造函数,初始化对象 n//等价于operator new
List* n2 = (List*)operator new(sizeof(List));
new(n2)List;
//等价于 delete
n2->~List();
//调用析构函数,析构函数是可以显示调用的,但是构造函数不能。
operator delete(n2);
}
推荐阅读
- 编程语言|程序员最讨厌的11句话 | 每日趣闻
- C++|DAY2 OpenCv学习笔记( C++ 透视变换)
- 安全|OpenHarmony安全子系统之应用签名与验签
- C语言和C++区别——C和C++之间互相调用
- Linux|管道实现进程间通信之命名管道
- c++|STL中string类的实现(细节避坑)
- c++|C++类和对象相关内容详细总结(值得收藏喔~)
- C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
- c++|唠唠C++入门那些事