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++ 风格 |
适合简单内存申请(不需要对象管理) | 适合对象创建与销毁(有构造析构过程) |