【C++】new和delete隐藏的秘密!!!

       在c语言里面有malloc、realloc和calloc来动态的开辟内存,对于这些函数的用法,在之前的文章里面有具体的用法介绍。

       但是在C++里面有new和delete来动态的开辟内存,同时C语言里面的动态开辟内存的函数也是可以使用的,那么有函数可以实现动态的内存开辟,为什么还要重新定义new和delete关键字来动态的开辟内存呢?

       这里注意,new和delete是关键字而不是函数,下面是一个C++里面的动态内存开辟的栗子:

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
	int *p1 = new int;
	int *p2 = new int(0);
	int *p3 = new int[10];
	
	//Doing something...

	delete p1;
	delete p2;
	delete[] p3;
	return 0;
}

       首先,new是用来动态的开辟堆上的内存,与之相应的释放内存的关键字是delete,在使用new来开辟内存的时候只需要在new后面跟上需要开辟的内存的类型,如果需要初始化可以new +数据类型(初始化值),有的时候我们会需要一次不止开辟一块这样的内存,这时候可以new+数据类型 [需要的个数 ]

class Date
{
public:
	Date(int year,int month,int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{
		cout<<"Date()"<<this<<endl;
	}
	~Date()
	{
		cout<<"~Date()"<<this<<endl;
	}

private:
	int _year;
	int _month;
	int _day;
};


int main()
{
	Date* d1 = new Date(2017,9,16);
	delete d1;
	return 0;
}

       在这段代码里面使用new来开辟一段Date大小的内存并且初始化,但是在调用的时候就会出现以下的结果:


        在C++里面的new看开辟的内存在开辟内存的时候不仅仅是开辟一段所需大小的内存同时还会调用构造函数和析构函数,但是在malloc里面只是开辟一块这样大小的内存,然后返回一个void*类型的指针,没有开辟成功就返回一个NULL。

       但从这点上面就可以看出来new的操作的malloc要相对的简单一些,但是有的时候不小心或者理解不够深,new和delete或者new[]和delete[]没有配对只用,那么程序依然会出现一些意想不到的后果,这里也要再三注意,使用的时候一定要配对使用new和delete、new[]和delete[]一定要配对使用new和delete、new[]和delete[] 
一定要配对使用new和delete、new[]和delete[]

       细心的程序猿可能会观察到使用new[]的时候是创建n个需要类型大小的内存,原因是,在使用new创建一块内存的时候会在开辟的内存前面在开辟四个字节大小的空间,这个空间就是用来存储n值 的,同样,在delete[]的时候,先调用n的值,然后在去释放掉动态开辟的内存。

       这也间接说明了,如果在使用new[]来开辟内存的时候用delete来释放的话,就没有办法来寻找n值,这时候程序就会出现意想不到的后果。总之,使用的时候一定要小心,一定要成对使用,一定要匹配使用,切勿滥用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的`new`和`delete`是用于动态内存分配和释放的运算符。它们的底层实现是通过调用C++标准库中的`operator new`和`operator delete`函数来完成的。 `operator new`函数的原型如下: ```cpp void* operator new(std::size_t size); ``` 它接受一个参数`size`,表示要分配的内存大小,返回一个指向分配的内存块的指针。当内存不足时,`operator new`函数会抛出`std::bad_alloc`异常。 `operator new`函数的实现方式可以是调用操作系统提供的内存分配函数,也可以是通过维护一块大的内存池来实现。具体实现方式因编译器和操作系统而异。 `operator delete`函数的原型如下: ```cpp void operator delete(void* ptr) noexcept; ``` 它接受一个参数`ptr`,表示要释放的内存块的指针。`operator delete`函数不会抛出异常,因此需要使用`noexcept`关键字来声明。 `operator delete`函数的实现方式通常是调用操作系统提供的内存释放函数来实现。 在使用`new`和`delete`时,我们可以重载`operator new`和`operator delete`函数来自定义内存分配和释放的方式。例如,我们可以使用一个内存池来实现高效的内存分配和释放。 下面是一个简单的例子: ```cpp #include <iostream> #include <cstdlib> void* operator new(std::size_t size){ std::cout << "Allocating " << size << " bytes" << std::endl; void* p = std::malloc(size); if(!p){ throw std::bad_alloc(); } return p; } void operator delete(void* ptr) noexcept{ std::cout << "Deallocating memory" << std::endl; std::free(ptr); } int main(){ int* p = new int; delete p; return 0; } ``` 输出结果为: ``` Allocating 4 bytes Deallocating memory ``` 可以看到,我们重载的`operator new`和`operator delete`函数成功地被调用了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值