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++ 风格
适合简单内存申请(不需要对象管理) 适合对象创建与销毁(有构造析构过程)
相关推荐
阳洞洞12 分钟前
leetcode 2516. 每种字符至少取 K 个
算法·leetcode·滑动窗口
Wooden-Flute37 分钟前
十一、引用与拷贝函数(References & the Copy-Constructor)
c++
fpcc1 小时前
跟我学C++中级篇——控制死锁
c++·软件工程
wjm0410061 小时前
C++日更八股--first
java·开发语言·c++
菜还不练就废了2 小时前
数据结构|并查集
数据结构·算法
heyCHEEMS2 小时前
[USACO09OCT] Bessie‘s Weight Problem G Java
java·开发语言·算法
凢en2 小时前
NOC科普一
网络·笔记·算法·智能路由器·硬件工程
RanceGru2 小时前
C++——调用OpenCV和NVIDIA Video Codec SDK库实现使用GPU硬解码MP4视频文件
c++·opencv·算法·gpu算力·视频编解码
十一29283 小时前
指针变量存放在哪?
内存管理·操作系统的虚拟内存机制