new b

Last edited time
Sep 17, 2024 10:58 AM
AI summary
newmalloc 的主要区别在于内存分配的安全性、构造函数的调用、返回类型、内存分配失败时的处理以及对数组的支持。new 会检查内存分配是否成功并调用构造函数,而 malloc 仅分配内存并返回 void* 指针,需手动转换类型。new 在失败时抛出异常,而 malloc 返回 NULL。此外,new 支持数组的构造和析构,而 malloc 需要手动管理内存。总的来说,在 C++ 中使用 new/delete 更符合面向对象编程的需求。
Last edited by
Tags
参考: 前⾔。
malloc 只是简单的申请内存, new 还会检查是否申请成功,并且负责调⽤构造函数(如果有的话), new ⽐ malloc 要好的多,建议使⽤。其实,在 new 中,也是调⽤ malloc 申请内存的,只不过封装的更好,更安全。
  • 申请时的内存所在位置
    • new 操作从⾃由存储区上为对象动态分配内存空间,⽽ malloc 函数从堆上为对象动态地分配内存空间。⾃由存储区是C++基于 new 操作符的⼀个抽象概念,凡是通过 new 操作符进⾏内存申请,该内存即为⾃由存储区。⽽堆是操作系统中的术语,是操作系统所维护的⼀块特殊内存,⽤于程序的内存动态分配,C语⾔使⽤ malloc 从堆上分配内存,使⽤ free 释放已分配的对应内存。
  • 那么⾃由存储区和堆区的区别?或者说那么⾃由存储区是否能够是堆(问题等价于new是否能在堆上动态分配内存)?
    • 这取决于 new  操作符的实现细节。⾃由存储区不仅可以是堆,还可以是静态存储区,这得看  new  操作符在哪⾥为对象分配内存。特别的, new 甚⾄可以不为对象分配内存,⽐如定位new —⼈为找到⼀块分配内存的地址,⽽不让系统随机分配地址。
  • new operator 和 operator new 的区别?调⽤new的时候编译器做了什么?
    • new 就是 new operator ,调⽤ new 的时候编译器做了三件事:
      1. operator new( ) 分配内存。new的底层是调⽤operator new( )分配内存的。该函数调⽤malloc申请内存。
      1. 是调⽤构造函数(就是new 的类类型或者 string 等类型的构造函数)。这⼀步是使⽤ placement new(定位new) 来实现的, 即在取得了⼀块可以容纳指定类型对象的内存之后,在这块内存上构造⼀个对象
      1. 返回相应数据类型的指针。

new(new operator) 和 malloc 的主要区别。

  1. 返回类型的安全性
    1. new 操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故  new  是符合类型安全性的操作符。而 malloc 内存分配成功则是返回 void * ,需要通过强制类型转换将 void* 指针转换成我们需要的类型。类型安全很⼤程度上可以等价于内存安全,类型安全的代码不会试图分配⾃⼰没被授权的内存区域。
  1. 内存分配失败时的返回值
    1. new 内存分配失败时,会抛出 bac_alloc异常 ,它不会返回 NULL ; malloc 分配内存失败时返回 NULL 
  1. 是否需要指定内存⼤⼩
    1. 使⽤ new 操作符申请内存分配时⽆须指定内存块的⼤⼩,编译器会根据类型信息⾃⾏计算,⽽ malloc 则需要显式地指出所需内存的尺⼨。
  1. 是否调⽤构造函数/析构函数
    1. 使⽤new操作符来分配对象内存时会经历三个步骤:
      • 调⽤ operatornew 函数(对于数组是operator new[])分配⼀块⾜够⼤的,原始的,未命名的内存空间以便存储特定类型的对象。
      • 编译器运⾏相应的构造函数以构造对象,并为其传⼊初值。
      • 对象构造完成后,返回⼀个指向该对象的指针。
      使⽤delete操作符来释放对象内存时会经历两个步骤:
      • 调⽤对象的析构函数。
      • 编译器调⽤operatordelete(对于数组是 operator delete[])函数释放内存空间。
      总之来说, new/delete 会调用对象的构造函数/析构函数以完成对象的构造/析构,⽽ malloc 则不会。例⼦如下:
      在 return 处设置断点,观看 ptr 所指内存的内容:
      可以看出 A 的默认构造函数并没有被调⽤,因为数据成员 a,b 的值并没有得到初始化。⽽⽤ new 来分配对象是,可以看到 A 的默认构造函数被调用了。
  1. 对数组的处理
    1. C++提供了 new[] 与 delete[] 来专门处理数组类型:
      new 对数组的支持体现在它会分别调用构造函数函数初始化每⼀个数组元素,释放对象时为每个对象调用析构函数。注意  delete[]  要与 new[] 配套使⽤,不然会出现数组对象部分释放的现象,造成内存泄漏。
      ⾄于  malloc   ,它并知道你在这块内存上要放的数组还是啥别的东西,反正它就给你⼀块原始的内存,在给你个内存的地址就完事。所以如果要动态分配⼀个数组的内存,还需要我们手动自定数组的大小:
  1. new与malloc是否可以相互调用
    1. new 的实现(operator new /operator delete)可以基于 malloc,只是封装的更好,更安全。⽽malloc的实现不可以去调⽤new。
  1. 是否可以被重载
    1. opeartor new /operator delete 可以被重载。标准库是定义了operator new函数和operator delete函数的8个重载版本,我们有⾜够的⾃由去重载 operator new /operator delete ,以决定我们的 new/delete 如何为对象分配内存,如何回收对象。⽽ malloc/free 并不允许重载。
  1. 能否直观地重新分配内存
    1. 使⽤ malloc 分配的内存后,如果在使⽤过程中发现内存不⾜,可以使⽤ realloc 函数进⾏内存重新分配实现内存的扩充。 realloc 先判断当前的指针所指内存是否有足够的连续空间,如果有,原地扩⼤可分配的内存地址,并且返回原来的地址指针;如果空间不够,先按照新指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来的内存区域。(类似于 vector 的扩容)。
      而 new 没有这样直观的配套设施来扩充内存。
  1. 客户处理内存分配不足
    1. 在 operator new 抛出异常以反映⼀个未获得满足的需求之前,它会先调⽤一个用户指定的错误处理函数,这就是 new-handler ,这个函数程序员可以重新编写决定内存不足以分配时要干什么事。而   malloc   ,客户并不能够去自定义编程决定内存不足以分配时要干什么事, 只能看着 malloc 返回 NULL 
总结:malloc给你的就好像⼀块原始的土地,你要种什么需要自己在土地上来播种。而new帮你划好了田地的分块(数组),帮你播了种(构造函数),还提供其他的设施供用户使用。在C++这种偏重OOP的语言,使用new/delete是更合适的。

new 的用法:

参考:
new  的根本用法就是为某个变量动态地分配内存,主要有下面两种用法:
  1. 负责在自由存储区中找到⼀个⾜以能够满⾜要求的内存块。
    1. 定位new运算符(placement new) ,它能够让程序员指定要使用的位置。既将new运算符用于提供了的地址。 定位new运算符 不需要相应的  delete运算符  来释放内存。因为它本身就不开辟新的内存,只是返回将要使用的地址,并将其强制转换为void  *,以便我们能够通过强制类型转换将 void *指针赋给任何指针类型。
    Loading...