当前位置: 首页 > news >正文

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

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


一、new/deletemalloc/free 的区别

特性new/deletemalloc/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 示例

#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 示例

#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[](数组版本)

#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;
}

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

项目说明
1newdelete 要成对使用
2new[]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)避免手动管理内存错误

五、常见错误示例

// 错误示例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/freenew/delete
只分配/释放内存,不调用构造析构函数分配内存并调用构造/析构函数
返回 void*返回对应类型的指针
C 风格C++ 风格
适合简单内存申请(不需要对象管理)适合对象创建与销毁(有构造析构过程)

相关文章:

  • 如何搭建spark yarn 模式的集群集群
  • 贝叶斯优化RF预测模型
  • MYSQL三大日志、隔离级别(MVCC+锁机制实现)
  • 【深度学习与大模型基础】第14章-分类任务与经典分类算法
  • Vue2 相关知识点整理
  • 数据结构---单链表的增删查改
  • 第十六届蓝桥杯 2025 C/C++组 25之和
  • 【Bash】可以请您解释性地说明一下“2>1”这个语法吗?
  • 基于tabula对pdf中多个excel进行识别并转换成word中的优化(四)
  • 关于插值和拟合(数学建模实验课)
  • 【记】Laya2.x数字末尾导致换行异常问题
  • C# 14 field keyword:属性简化新利器
  • 基于PyTorch的Fashion-MNIST图像分类数据集处理与可视化
  • Java后端图形验证码的使用
  • [Linux网络_68] 转发 | 路由(Hop by Hop) | IP的分片和组装
  • 当OA闯入元宇宙:打卡、报销和会议的未来狂想
  • 【C++11】包装器:function与bind
  • 【BotSharp框架示例 ——实现聊天机器人,并通过 DeepSeek V3实现 function calling】
  • 【MuJoCo仿真】开源SO100机械臂导入到仿真环境
  • 在 Ubuntu 上离线安装 ClickHouse
  • 浙商银行一季度净赚超59亿微增0.61%,非息净收入降逾22%
  • 韩国下届大选执政党初选4进2结果揭晓,金文洙、韩东勋胜出
  • 千亿市值光储龙头董事长向母校合肥工业大学捐赠1亿元
  • 亮剑浦江丨上海网信部门处罚一批医疗服务类互联网企业,三大类问题值得关注
  • 从“网点适老化”到“社区嵌入式”,“金融为老上海模式”如何探索?
  • 王羲之《丧乱帖》在日本流传了1300年,将在大阪展23天