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

C++ 中 new/deletemalloc/free 完全详解


一、new/deletemalloc/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 newdelete 要成对使用
2 new[]delete[] 要成对使用不是 delete!!!
3 不要混用 mallocdelete,或 newfree严重错误!
4 避免内存泄漏:申请的内存必须释放,否则内存泄漏
5 申请后立即检查返回值malloc 返回 NULL,new 可以捕捉异常
6 构造/析构问题malloc 不负责对象构造,new
7 自定义 new/delete :可以通过重载 operator new / operator delete 控制内存分配策略(如内存池优化)
8 异常安全 :尽量使用智能指针(如 std::unique_ptrstd::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++·算法·
小蒋学算法3 小时前
算法-删除元素后最大固定点数目-典型最长增长序列算法
数据结构·算法
RD_daoyi3 小时前
Google偷偷给AI引用加了五个新功能:内联引用、悬停预览、品牌展示……但点击率真的回来了吗?
大数据·网络·人工智能·算法·安全·搜索引擎
船漏了就会沉3 小时前
后缀自动机(SAM):字符串处理的“万能瑞士军刀”
算法
醉城夜风~3 小时前
C++模板详解:从基础到高级全面解析
java·开发语言·c++
RuiZN4 小时前
Muduo---Channel类
运维·服务器·c++
誰能久伴不乏4 小时前
深入理解 C++ 多态:对象模型与底层机制解析
开发语言·c++·架构
ShineWinsu4 小时前
对于Linux:自定义协议(基于TCP)实现网络计算器的解析
linux·网络·c++·网络协议·tcp/ip·面试·网络计算器
郝学胜-神的一滴4 小时前
中级OpenGL教程 026:Assimp库从编译到实战全攻略
c++·unity·游戏引擎·图形渲染·unreal engine·opengl
今夜有雨.4 小时前
C++JSON 解析器
c++·笔记·后端·学习·json