C++ new/delete 与 malloc/free 的区别?

  1. 分配内存的位置
    1. malloc是从上动态分配内存
    2. new是从自由存储区为对象动态分配内存。自由存储区的位置取决于operator new的实现。自由存储区不仅可以为堆,还可以是静态存储区,这都看operator new在哪里为对象分配内存
  2. 是否可以被重载
    1. opeartor new 、operator delete 可以被重载
    2. malloc、free则不能重载
  3. 内存分配
    1. malloc内存分配成功后返回void*,然后再强制类型转换为需要的类型
      1. malloc内存分配失败后返回 NULL
    2. new操作符分配内存成功后返回与对象类型相匹配的指针类型;因此new是符合类型安全的操作符
      1. new分配内存失败则会抛异常 std::bad_alloc
      2. 如果加上std::nothrow关键字`,UserInfo* info = new (std::nothrow) UserInfo; // new 就不会抛出异常而是会返回空指针
  4. 分配内存的大小的计算
    1. 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算
    2. malloc则需要显式地指出所需内存的尺寸
  5. 使用场景
    1. new/delete 适用于C++对象,它们会自动处理对象的构造和析构。
    2. malloc/free 更通用,可以在C++中使用,也可以在C中使用,但需要手动管理对象的构造和析构。
// 使用 malloc 分配内存 并 强制类型转换
UserInfo* user = static_cast<UserInfo*>(malloc(sizeof(UserInfo)));

// 构造对象
new (user) UserInfo("Alice", 25);

// 使用对象指针调用成员函数
std::cout << "User's age: " << user->getAge() << std::endl;

// 手动调用析构函数
user->~UserInfo();

// 释放内存
free(user);
  • Malloc 函数用于动态分配内存。为了减少内存碎片和系统调用的开销,malloc 其采用内存池的方式,先申请大块内存作为堆区,然后将堆区分为多个内存块,以块作为内存管理的基本单位。
  • 当用户申请内存时,直接从堆区分配一块合适的空闲块。
  • Malloc 采用隐式链表结构将堆区分成连续的、大小不一的块,包含已分配块和未分配块;同时 malloc 采用显示链表结构来管理所有的空闲块,即使用一个双向链表将空闲块连接起来,每一个空闲块记录了一个连续的、未分配的地址。
  • 当进行内存分配时,Malloc 会通过隐式链表遍历所有的空闲块,选择满足要求的块进行分配;当进行内存合并时,malloc 采用边界标记法,根据每个块的前后块是否已经分配来决定是否进行块合并。
  • Malloc 在申请内存时,一般会通过brk或者mmap 系统调用进行申请。其中当申请内存小于128K 时,会使用系统函数brk 在堆区中分配;而当申请内存大于128K 时,会使用系统函数mmap 在映射区分配。
/**
 * 通过重载new和delete关键字来自定义内存分配和释放操作,以满足特定需求
 * new:分配单个对象的内存。
 * new[]:分配一个数组的内存。
 * new (std::nothrow):分配内存但不抛出异常。
 * new[] (std::nothrow):分配数组的内存但不抛出异常。
 */
void* operator new(size_t size) {
    std::cout << "Custom new called. Size: " << size << std::endl;//16
    void* memory = std::malloc(size);
    if (!memory) {
        throw std::bad_alloc();
    }
    return memory;
}

void operator delete(void* ptr) noexcept {
    std::cout << "Custom delete called." << std::endl;
    std::free(ptr);
}


int main() {
   Data* data = new Data();
   delete data;
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值