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++ 风格
适合简单内存申请(不需要对象管理) 适合对象创建与销毁(有构造析构过程)
相关推荐
KyollBM4 分钟前
【Luogu】每日一题——Day15. P1144 最短路计数 (记忆化搜索 + 图论 + 最短路)
算法·图论
一百天成为python专家12 分钟前
K-近邻算法
数据结构·python·算法·pandas·近邻算法·ipython·python3.11
满分观察网友z30 分钟前
告别烦人的“三连发”:我的智能评论系统过滤之旅(1957. 删除字符使字符串变好)
算法
满分观察网友z33 分钟前
滑动窗口下的极限挑战:我在实时数据流中挖掘最大价值分(1695. 删除子数组的最大得分)
算法
从0至134 分钟前
C++编程入门:从基础到复合类型
开发语言·c++
山烛1 小时前
KNN 算法中的各种距离:从原理到应用
人工智能·python·算法·机器学习·knn·k近邻算法·距离公式
guozhetao1 小时前
【ST表、倍增】P7167 [eJOI 2020] Fountain (Day1)
java·c++·python·算法·leetcode·深度优先·图论
吃着火锅x唱着歌1 小时前
LeetCode 611.有效三角形的个数
算法·leetcode·职场和发展
CHANG_THE_WORLD4 小时前
金字塔降低采样
算法·金字塔采样
不知天地为何吴女士6 小时前
Day32| 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
算法