C++ 中自主内存管理 new/delete 与 malloc/free 完全详解

C++ 中 new/delete 与 malloc/free 完全详解


一、new/delete 与 malloc/free 的区别

特性 new/delete malloc/free
属于 C++语言 C语言
申请的内存区 堆(Heap) 堆(Heap)
返回类型 指向对象类型的指针(自动转换) void*,需手动强制转换类型
是否调用构造函数 是(调用构造函数) 否(只分配内存,不调用构造函数)
是否调用析构函数 是(调用析构函数) 否
申请失败 抛出异常(std::bad_alloc) 返回 NULL

二、详细解释

1. malloc/free(C语言风格)

  • malloc(size_t size):申请一块连续的内存区域,大小为 size 字节。
  • 返回 void*,需要强制类型转换成需要的指针类型。
  • 不会调用对象的构造函数,只是单纯分配内存。
  • free(void* ptr):释放由 malloc 分配的内存,不调用析构函数。

使用场景:

  • 兼容 C 的项目
  • 只需要原始内存、不需要对象初始化时

2. new/delete(C++风格)

  • new Type(args):分配内存 + 调用构造函数。
  • delete ptr:调用析构函数 + 释放内存。
  • 可以分配单个对象,也可以分配数组对象(new Type[n])。

使用场景:

  • 需要构造和析构管理的 C++ 对象
  • 更安全、更易用,符合 C++ RAII 风格

三、常见使用示例

1. malloc/free 示例

cpp 复制代码
#include <cstdlib>  // for malloc/free
#include <iostream>

struct MyStruct {
    int x;
    float y;
};

int main() {
    // malloc 分配内存
    MyStruct* p = (MyStruct*)malloc(sizeof(MyStruct));
    if (p == nullptr) {
        std::cerr << "Memory allocation failed!" << std::endl;
        return 1;
    }

    // 手动初始化
    p->x = 10;
    p->y = 3.14f;

    std::cout << "x = " << p->x << ", y = " << p->y << std::endl;

    // free 释放内存
    free(p);

    return 0;
}

2. new/delete 示例

cpp 复制代码
#include <iostream>

struct MyStruct {
    int x;
    float y;

    // 构造函数
    MyStruct(int a, float b) : x(a), y(b) {
        std::cout << "Constructor called!" << std::endl;
    }

    // 析构函数
    ~MyStruct() {
        std::cout << "Destructor called!" << std::endl;
    }
};

int main() {
    // new 分配并调用构造函数
    MyStruct* p = new MyStruct(10, 3.14f);

    std::cout << "x = " << p->x << ", y = " << p->y << std::endl;

    // delete 调用析构函数并释放
    delete p;

    return 0;
}

3. new/delete\[\](数组版本)

cpp 复制代码
#include <iostream>

int main() {
    // 分配一个数组
    int* arr = new int[5];

    for (int i = 0; i < 5; ++i)
        arr[i] = i * 10;

    for (int i = 0; i < 5; ++i)
        std::cout << arr[i] << " ";
    std::cout << std::endl;

    // 必须使用 delete[] !!!
    delete[] arr;

    return 0;
}

四、注意事项总结(超级重要)

项目 说明
1 new 和 delete 要成对使用
2 new[] 和 delete[] 要成对使用 (不是 delete!!!)
3 不要混用 malloc 和 delete,或 new 和 free (严重错误!)
4 避免内存泄漏:申请的内存必须释放,否则内存泄漏
5 申请后立即检查返回值 :malloc 返回 NULL,new 可以捕捉异常
6 构造/析构问题 :malloc 不负责对象构造,new 是
7 自定义 new/delete :可以通过重载 operator new / operator delete 控制内存分配策略(如内存池优化)
8 异常安全 :尽量使用智能指针(如 std::unique_ptr、std::shared_ptr)避免手动管理内存错误

五、常见错误示例

cpp 复制代码
// 错误示例1:malloc分配,用delete释放
int* p = (int*)malloc(sizeof(int));
delete p;  // ❌ 错,应使用 free(p);

// 错误示例2:new分配,用free释放
int* q = new int(5);
free(q);  // ❌ 错,应使用 delete q;

// 错误示例3:new[]配delete
int* arr = new int[10];
delete arr;  // ❌ 错,应使用 delete[] arr;

小结

malloc/free new/delete
只分配/释放内存,不调用构造析构函数 分配内存并调用构造/析构函数
返回 void* 返回对应类型的指针
C 风格 C++ 风格
适合简单内存申请(不需要对象管理) 适合对象创建与销毁(有构造析构过程)
相关推荐
个 人 练 习 生3 分钟前
C++中的内存管理
开发语言·c++·经验分享·学习
续写烂尾4 分钟前
MK SD NAND(贴片式TF卡)替代Nor Flash:1Gb容量与256Mb Nor
算法·microsoft
u01110267536 分钟前
图片预览越来越占内存聊聊 URL.createObjectURL 的释放时机
图像处理·深度学习·算法·ai作画
Zane199437 分钟前
同样是遍历图,为什么BFS能保证找到最短路径,DFS却不行
算法
无限码力37 分钟前
2026华为OD机试真题 新系统 9月27日【坚果巧克力】
算法·华为od·华为od机考·华为od机试真题·华为od机试·华为od机考真题题解·华为社招笔试真题
samforce41 分钟前
叹息之墙——人类认知 AI,终将遇到的一堵同构之墙
人工智能·深度学习·算法·哲学·认知科学
艾莉丝努力练剑1 小时前
【AI大模型接入SDK】ChatSDK整体实现
网络·c++·人工智能·学习·架构
励志不掉头发的内向程序员1 小时前
【从零写一个CAD 02】画完第一条线之后:实体容器、Esc 取消,和按了没反应的键盘
开发语言·c++·qt·学习·系统架构
l1t1 小时前
编译测试兼容gzip并行压缩解压工具pigz
c++·算法
无名猿1 小时前
对象存储期全解:automatic / static / dynamic / thread
c++·内存管理·现代c++·语法基础