C++ 中 malloc 和 delete 的混用问题
简短回答
不可以! malloc 申请的内存必须用 free 释放,new 申请的内存必须用 delete 释放。
为什么不能混用?
1. 内存分配机制不同
// malloc/free – C 风格
void* ptr = malloc(sizeof(int));
free(ptr); // ✓ 正确
// new/delete – C++ 风格
int* ptr2 = new int;
delete ptr2; // ✓ 正确
2. 混用的后果
// 错误示例 1: malloc + delete
int* ptr = (int*)malloc(sizeof(int));
delete ptr; // ✗ 未定义行为!可能导致崩溃或内存泄漏
// 错误示例 2: new + free
int* ptr2 = new int;
free(ptr2); // ✗ 未定义行为!可能导致崩溃或内存泄漏
详细原因
1. malloc vs new 的区别
| 语言 | C | C++ |
| 类型安全 | 返回 void*,需要强制转换 | 返回正确类型的指针 |
| 构造/析构 | 不调用构造函数和析构函数 | 调用构造函数和析构函数 |
| 内存分配 | 只分配原始内存 | 分配内存并初始化对象 |
| 失败处理 | 返回 nullptr | 抛出 std::bad_alloc 异常 |
| 重载 | 不可重载 | 可以重载 |
2. 内部实现差异
// malloc 分配的内存布局
// [元数据][原始内存]
// free 需要读取元数据来释放
// new 分配的内存布局
// [元数据][对象内存][可能的额外信息]
// delete 需要调用析构函数,然后释放内存
正确的使用方式
C 风格(C++ 中也可以用)
#include <cstdlib>
void* ptr = malloc(100); // 分配 100 字节
if (ptr) {
// 使用内存…
free(ptr); // 释放
}
C++ 风格(推荐)
// 基本类型
int* ptr = new int(42);
delete ptr;
// 数组
int* arr = new int[10];
delete[] arr; // 注意:数组要用 delete[]
// 对象
class MyClass {
public:
MyClass() { std::cout << "Constructor\\n"; }
~MyClass() { std::cout << "Destructor\\n"; }
};
MyClass* obj = new MyClass();
delete obj; // 会调用析构函数
最佳实践
1. 优先使用智能指针(C++11+)
#include <memory>
// 使用 unique_ptr(独占所有权)
std::unique_ptr<int> ptr = std::make_unique<int>(42);
// 自动释放,无需手动 delete
// 使用 shared_ptr(共享所有权)
std::shared_ptr<int> ptr2 = std::make_shared<int>(42);
// 引用计数归零时自动释放
2. 使用标准容器
#include <vector>
std::vector<int> vec(100); // 自动管理内存
// 无需手动释放
3. RAII 原则
class Resource {
private:
int* data;
public:
Resource(size_t size) : data(new int[size]) {}
~Resource() { delete[] data; } // 析构时自动释放
// 禁止拷贝
Resource(const Resource&) = delete;
Resource& operator=(const Resource&) = delete;
};
特殊情况说明
placement new
// 在预分配的内存上构造对象
void* raw = malloc(sizeof(MyClass));
MyClass* obj = new(raw) MyClass; // placement new
// 需要手动调用析构函数,然后释放原始内存
obj->~MyClass(); // 调用析构函数
free(raw); // 释放原始内存
总结
| malloc | free | ✓ |
| calloc | free | ✓ |
| realloc | free | ✓ |
| new | delete | ✓ |
| new[] | delete[] | ✓ |
| malloc | delete | ✗ 未定义行为 |
| new | free | ✗ 未定义行为 |
核心原则:成对使用,不要混用!在现代 C++ 中,优先使用智能指针和标准容器来避免手动内存管理。




