new /delete和malloc/free

1.C++ 使用 new 和 delete 操作符进行动态内存分配和释放的原因主要有以下几点:

动态内存管理:
在C++中,局部变量(包括数组)通常是在栈上分配的,其生命周期由它们的作用域决定。然而,有时候我们需要在程序的运行时根据需求动态地分配和释放内存。这时,new 和 delete 就派上了用场。它们允许我们在堆上分配内存,并且这块内存的生命周期不受作用域的限制,直到显式地使用 delete 或 delete[] 释放为止。
对象生命周期控制:
对于C++中的对象,new 操作符在分配内存的同时还会调用对象的构造函数进行初始化。同样地,delete 操作符在释放内存之前会调用对象的析构函数进行清理工作。这使得我们可以更加精细地控制对象的生命周期和资源管理。
处理大型数据结构:
当需要处理大型数据结构(如大型数组或复杂的数据结构)时,使用 new 在堆上分配内存通常比在栈上分配更加高效。栈的大小通常是有限的,而堆的大小则取决于系统的可用内存。
实现抽象数据结构:
在C++中,我们经常需要实现一些抽象数据结构(如链表、树、图等)。这些数据结构通常需要在运行时动态地创建和销毁节点。使用 new 和 delete 可以方便地实现这种需求。
与C语言库的兼容性:
虽然C++提供了更高级的内存管理机制(如智能指针),但在某些情况下,我们可能需要与C语言库或API进行交互,这些库或API可能使用 malloc 和 free 进行内存管理。在这种情况下,使用 new 和 delete 可以更容易地与这些库或API集成。
代码清晰性和可维护性:
使用 new 和 delete 可以使代码更加清晰和易于维护。通过显式地分配和释放内存,我们可以更容易地跟踪和管理内存的使用情况,从而避免内存泄漏和其他与内存相关的问题。
需要注意的是,虽然 new 和 delete 提供了强大的动态内存管理能力,但它们也带来了一定的风险。如果忘记释放已分配的内存或多次释放同一块内存,都可能导致程序崩溃或数据损坏。因此,在使用 new 和 delete 时需要格外小心,并确保正确地管理内存。为了避免这些问题,C++11及以后的版本引入了智能指针(如 std::unique_ptr 和 std::shared_ptr),它们可以自动管理内存的生命周期,从而减少了内存泄漏和重复释放的风险。

new和delete是C++向内存申请空间和释放空间的操作符, C++为什么要使用new和delete?

1.C语言使用malloc、calloc、realloc、free管理的不便之处在于:

(1)手动申请内存需要手动计算字节数的大小

(2)对返回值类型void *要进行强转,否则无法解引用

(3)内存是否申请成功需要对返回值进行判空

(4)需要include头文件<stdlib.h>

2.new和delete的使用对自定义类型会进行处理:

(1)new会调用构造函数对类对象进行初始化

(2)delete会调用析构函数进行资源清理

2.为什么说使用 char* p = new char[100]申请一段内存,然后使用delete p释放,为什么对于内置型,此时delete就相当于free,因此不会造成内存泄漏?

在C++中,new 和 delete 操作符是用于动态内存分配和释放的主要机制。对于基本数据类型(或称为内置类型,如 char, int, double 等),new 和 delete 确实在行为上与C语言中的 malloc 和 free 类似,但它们在C++的上下文中具有更多的功能和安全性。

当你说 char* p = new char[100];,new 操作符在这里做了几件事情:

它在堆上分配了足够存储100个字符的内存块。
它返回这块内存的起始地址,并将其赋给指针 p。
对于内置类型,new 并不调用构造函数(因为内置类型没有构造函数)。
然后,当你使用 delete[] p; 释放这块内存时,delete[] 操作符会:

调用数组中每个元素的析构函数(对于内置类型,这一步不会发生,因为内置类型没有析构函数)。
释放之前由 new 分配的内存块。
对于内置类型,由于它们没有析构函数,因此 delete[] 在释放内存时不会执行任何额外的清理工作(除了释放内存本身)。这就是为什么在这种情况下,你可以说 delete[] 对于内置类型来说行为上类似于 free。

然而,重要的是要明白 delete[] 和 free 在C++中并不等价。delete[] 是C++操作符,它知道之前是通过 new[] 分配的数组,因此会正确地处理数组的内存释放。而 free 是C语言库函数,它只知道要释放一块内存,但不知道这块内存是如何分配的(例如,它不知道是否是一个数组)。如果你在C++中使用 malloc 和 free,你需要格外小心,以避免潜在的问题,如内存泄漏或双重释放。

最后,关于内存泄漏:当你使用 new 或 new[] 分配内存后,你必须使用相应的 delete 或 delete[] 来释放这块内存。否则,这块内存将保持分配状态,直到程序结束,这被称为内存泄漏。对于你的示例,只要你使用 delete[] p; 来释放内存,就不会造成内存泄漏,无论 p 指向的是内置类型还是其他类型的数组。

3.为什么说new/delete和malloc/free对内置类型的操作没有区别

对于内置类型(如int, double, char等)而言,new/delete和malloc/free在基本功能上的确没有明显区别,因为它们都会分配和释放所需的内存空间。但是,从细节和最佳实践的角度来看,它们之间存在一些重要的差异。

内存分配与初始化:
new不仅分配内存,还会调用构造函数(对于非内置类型)。这意味着对于内置类型,new和malloc的差别不大,因为内置类型没有显式的构造函数。但是,对于类类型,new会自动调用构造函数,而malloc不会。
delete在释放内存之前会调用析构函数(对于非内置类型)。同样,对于内置类型,这通常不是一个问题。
malloc只分配内存,不初始化它。对于内置类型,这通常不是问题,因为你可以手动设置它们的值。但是,对于复杂的数据结构或类类型,未初始化的内存可能导致问题。
异常安全性:
new在内存分配失败时会抛出std::bad_alloc异常。这使得它在异常处理方面更加安全。
malloc在内存分配失败时返回nullptr(在C11及更高版本中)。在C++中,如果你不小心忘记了检查malloc的返回值,可能会导致未定义行为。
类型安全性:
new和delete是C++的运算符,它们会返回正确类型的指针。这意味着你不需要进行类型转换。
malloc和free是C语言的库函数,它们返回void*类型的指针。在C++中,你需要进行显式的类型转换,这可能会降低代码的可读性和安全性。
内存对齐和填充:
C++编译器可能会为了性能或数据结构的完整性而添加内存对齐或填充。new会考虑这些,但malloc可能不会。这可能会导致与某些硬件或库的不兼容问题。
可移植性和标准化:
new/delete是C++标准的一部分,具有更好的可移植性和标准化。
malloc/free是C语言库函数,虽然在很多平台上都可用,但它们的行为可能会因实现而异。
现代C++实践:
在现代C++中,推荐使用智能指针(如std::unique_ptr和std::shared_ptr)来管理动态分配的内存。这些智能指针会自动调用delete来释放内存,从而减少了内存泄漏的可能性。
综上所述,虽然对于内置类型而言,new/delete和malloc/free在功能上可能没有明显区别,但从安全性、可读性、可移植性和最佳实践的角度来看,new/delete是更好的选择。


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值