c/c++中new与malloc的解法

1.我们先来讲述一下new和delete?

   在C++中new/delete是开辟/释放内存的,那他们与C语言中的malloc/free有什么区别呢?

 (1)new的底层是通过malloc来开辟内存的,但new比malloc多一项功能,那功能就是开辟完内存还要进行初始化操作。

          比如:new的基本操作为:int *p=new int(10);10代表堆上开辟的整型内存的初始值;Test *p=new Tset();这个操               作不仅会在堆上开辟Test类型大小的一块内存,还会调用Test类的默认构造函数构造一个对象,然而这时malloc办不到                   的!

 (2)delete比free多一项功能:在释放内存之前,还可以析构指针指向对象。new和delete配套使用,new【】和delete【】配套          使用。尽量不要交叉使用;

 (3)new的开辟内存失败是抛出bad_malloc类型异常,因此代码要捕获该类型的异常才正确的判断内存是否分配成功,malloc             内存开辟失败返回的是NULL指针;

(4)new和delete不仅是运算符,他们不仅是运算符重载函数的调用,对应函数名是operator new和operator delete,可以全局          或类中作用域提供自定义的new和delete运算符的重载函数 ,以改变默认的malloc和free内存开辟释放内存,比如实现内存             池。

2.什么时候用new【】申请,可以用delete释放?

   new和new【】的底层都是通过malloc来开辟内存,delete和delete【】的底层都是通过free来释放内存。那C++种为什么把单个元素的内存开辟释放和数组的内存开辟释放分开呢?因为在C++中开辟内存和构造对象是一起发生的,析构对象和内存是一起发生的。对于如下的类型:

int *p=new int ;   delete p;
 
int *p=new int ;   delete []p;
 
int *p=new int[10] ;  delete []p;
 
int *p=new int[10] ;  delete p;
   对于内置类型来说,这样混用是可以的,因为这个内置类型没有提供构造和析构函数,因此在这里的内存管理和调用malloc、free的含义是一样的,不会存在什么问题。但这样的代码是不符合编码规范的!!!

   对于如下的代码:

class  Test
{
  public:
 
   Test(){};
  
  private:
  
   int ma;
};
 
  Test *p=net Test;   delete p;
 
  Test *p=new Tset;   delete []p;
 
  Test *p=new Test[10];  delete []p;
 
  Test *p=new Test[10];   delete p;
    对于以上代码没有问题,因为这类没有提供析构函数,也就是说这个Test类对象不需要进行任何有效的析构,那么delete就只剩free的功能。那什么时候必须配套使用呢?接下来我们看看以下代码:

class Test
{
   public:
     
     Test(){};
       
     ~Test(){};
   
   private:
 
     int ma;
};
 
   Test *p=new Test;  delete p;//这个是OK的
 
   Test *p=new Test;  delete []p;//程序崩溃
 
   Test *p=new Test[10]; delete []p;//这个是OK的
 
   Test *p=new Test[10]; delete p;//程序崩溃
    这几行代码和上面的代码的不同点是:该代码有自定义的构造和析构函数。Test *p=new Test; delete []p;此行代码开辟了4个字节。当delete去释放内存时,那他是如何释放内存的,为什么释放4个字节?

    在这里我们自定义了析构函数,在释放内存前要析构对象。那我们写delete []p,编译器就会认为这里有很多对象要被析构,然而我们不知道有多少对象要被析构。记录对象个数的数字就在对象的4个字节存放着,他要从这里开始释放内存,然而这是错误的。

  因此,在我们用了自定义类型,而且还提供了析构函数时,new和delete要配套使用。

3.new和malloc的区别

 (1)malloc是函数,开辟内存需要传入需要字数,如malloc(100);表示在堆上开辟了100个字节的内存,返回void *,表示分配的堆内存的起始地址,因此malloc的返回值需要强转成指定的类型。new是运算符,开辟内存需要指定类型,返回指定的类型,因此不需要强转;

   (2)malloc和new都是在堆上开辟内存的。malloc指负责开辟内存,没有初始化功能,需要用户自己初始化;new不但开辟内存,还可以进行初始化;

(3)malloc开辟内存失败返回NULL,new开辟内存失败抛出bad_malloc类型的异常,需要捕获异常才能判断内存开辟内存成功或失败。new运算符其实是operator new函数的调用,它底层调用调用的是malloc来开辟内存。new他比malloc多的初始化功能。对于类型来说,所谓初始化就是调用相应的构造函数;

(4)malloc开辟的内存永远是通过free来释放的;而new是单个元素内存,用的delete。如果是new【】数组,用的delete【】来释放内存;

(5)malloc开辟的内存是只是一种方式,而new有四种,分别是普通的new(内存开辟内存失败抛出异常bad_malloc异常),northrow版本的new、const new以及定位new;

(6)重载。C++允许重载new/delete操作符,在布局new的就不需要作为对象分配牛从哪,而是指定一个地址作为内存起始地址,在这段内存上为对象调用构造函数完成初始化工作,并返回地址。而malloc不允许重载。

 4.有了malloc/free,为什还需要new/delete??

   malloc/free是C/C++中标准库函数,new/delete是C/C++中的关键字,都是开辟内存和释放内存的。malloc/free只能满足库内的数据类型,无法满足动态开辟对象的要求。对象在创建时调用构造函数,销毁时调用析构函数。malloc/free是库内提供的函数而不是运算符,不在编译器的范围之内,不能够把执行构造函数和析构函数的任务强加于他。C++需要一个能够完成开辟内存和调用构造函数的new,对象销毁时释放内存和调用析构函数的delete
————————————————
版权声明:本文为CSDN博主「つ微凉徒眸意浅挚半~~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/rjp_1987/article/details/104539467

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值