C++初阶语法——new,delete开辟/销毁动态内存空间

前言:在C语言中,有malloc,realloc,calloc开辟动态内存空间,free销毁动态内存空间。而在C++中,使用new开辟动态内存空间,delete销毁动态内存空间。不仅简化了操作,更为重要的是,解决自定义类型的初始化问题

一.简化操作

用法:new 类型 delete 指针
创建数组:new 类型[数据个数] delete[] 指针
编译器会自动计算类型大小,并且不用再强制转换类型。大大简化了操作,但是要记住下面这三句话:一定要匹配使用!匹配使用!匹配使用!

	//int* a = (int*)malloc(sizeof(int));
	//free(a);
	int* a = new int;
	delete a;
	int* b = new int[10];
	delete[] a;

二.解决自定义类型初始化问题(重点)

new/delete 和malloc/free最大的区别就是new/delete对于自定义类型除了开空间以外会去调用它们的构造函数/析构函数
new会调用构造函数,delete会调用析构函数。

以栈类为例:

typedef int DataType;
class Stack {
public:
	Stack(int capacity = 4)//构造函数 
	{
		_arr = new DataType[capacity];
		_capacity = capacity;
		_size = 0;
	}
	void StackPush(DataType Data)
	{
		_arr[_size] = Data;
		_size++;
	}
	~Stack() //析构函数
	{
		delete[] _arr;
		_capacity = _size = 0;
	}
private:
	DataType* _arr;
	int _capacity;
	int _size;
};
int main()
{
	Stack* ptr = (Stack*)malloc(sizeof(Stack)); //malloc开辟一个自定义的栈对象
	ptr->StackPush(1); //压栈
	free(ptr);
	return 0;
}

控制台显示如下:我们知道不为0代表着程序出错,那上面代码为什么出错呢?这就是我们强调的malloc只是单纯的开辟空间,不会去调用自定义类型Stack的构造函数,也就没有初始化,没有初始化还向里面压栈肯定会出现错误的。
在这里插入图片描述

改成new和delete则不会报错:

int main()
{
	Stack* ptr = new Stack;
	ptr->StackPush(1);
	delete ptr;
	//free(ptr)  不行,free不会去调用析构函数,资源得不到清理。
	return 0;
}

三.new不检查失败,抛异常

我们用malloc开辟空间时,一般都会写一个if条件语句防止开辟空间失败,而new不再检查失败,出错时会直接抛异常,也就是说用new的话不需要再写if条件防止开辟空间失败。

void Func()
{
	//malloc
	int* a = (int*)malloc(sizeof(int)*10);
	if (a == nullptr) //if判断
	{
		return;
	}
	free(a);
	//new
	int* b = new int[10];
	delete[] b;
}

1.抛异常

用malloc开辟同样大小的空间并不会提示错误,而new会。
在这里插入图片描述

2.捕获异常(try catch)

利用try和catch捕获异常,找到出现异常的原因。

int main()
{
	try
	{
		char* p2 = new char[0x7fffffff];
	}
	catch (const exception& error)
	{
		cout << error.what() << endl;
	}
	

控制台显示如下:
在这里插入图片描述

出现异常后会发生执行流跳跃,不执行异常后的代码:

int main()
{
	try
	{
		cout << "正常" << endl;
		char* p2 = new char[0x7fffffff];
		cout << "异常" << endl;
	}
	catch (const exception& error)
	{
		cout << error.what() << endl;
	}
	return 0;
}

控制台输出如下:可以看到,输出“异常”的代码并没有被执行。这点类似goto语句,出现异常之后,就直接跳到catch语句。这样的设计避免了出错了还运行后面的语句,防止错上加错。
在这里插入图片描述

四.operator new/operator delete函数

new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在地城调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

operator new是malloc函数的封装,也就是说,new出来的空间实际上是malloc出来的。不同的是,malloc函数出现错误会返回NULL,而C++需要的是出现错误返回异常,因此封装malloc函数,但出现错误返回异常。
operator delete原理与operator类似。

如下:operator new/operator delete使用方法与malloc/free相同。

	int* a = (int*)malloc(sizeof(int) * 10);
	free(a);
	int* b = (int*)operator new(sizeof(int) * 10);
	operator delete(b);

1.内置类型

由上,如果申请的是内置类型的空间,new和malloc,delete和free基本类似。不同的是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请和释放的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

以下三种方式都可以释放空间,实际上都是使用free释放空间。但是第一第二种并不推荐。使用时一定要匹配使用。以避免特殊情况出现。

	int* a = new int[10];
	//都可以释放申请的空间
	//free(a);
	//delete a;
	delete[] a;

2.自定义类型

  1. new的原理
    1.调用operator new函数申请空间
    2.在申请的空间上执行构造函数,完成对象初始化。
  2. delete的原理
    1.在空间上执行析构函数,完成对象中资源的清理工作。
    2.调用operator delete函数释放对象的空间。
  3. new T[n]的原理
    1.调用operator new[]函数,在operator new[]中实际调用operator new函数完成n个对象空间的申请。
    2.在申请的空间上执行n次构造函数
  4. delete[]的原理
    1.在释放的对象空间上执行n次析构函数,完成n个对象中资源的清理工作。
    2.调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间。

文末BB:对哪里有问题的朋友,尽管在评论区留言,若哪里写的有问题,也欢迎朋友们在评论区指出,博主看到后会第一时间确定修改。最后,制作不易,如果对朋友们有帮助的话,希望能给博主点点赞和关注.

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溪读卖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值