malloc
/free
和 new
/delete
是在 C++ 中分配和释放内存的两种不同方法。它们主要有以下区别:
1. 语法和用法
-
malloc
和free
: malloc开辟空间时需要手动计算分配的空间大小int* p = (int*)malloc(sizeof(int) * 10); // 分配10个int类型的内存 // 使用内存 free(p); // 释放内存
实际malloc在分配空间的时候会多给我们分配16个字节的空间(存储了内存块的描述信息),即16+mem。然后返回mem的首地址。然后free的时候,会以mem的地址左偏移16位,这样就知道能够释放多大的空间了。
-
new
和delete
: new开辟空间不需要手动计算分配的大小int* p = new int[10]; // 分配10个int类型的内存 // 使用内存 delete[] p; // 释放内存
2. 类型安全
malloc
和free
:malloc
返回void*
,需要显式转换为所需的类型指针,不提供类型安全。new
和delete
:new
直接返回所需类型的指针,不需要类型转换,提供类型安全。
3. 构造函数和析构函数
malloc
和free
: 只分配和释放原始内存,不调用构造函数和析构函数。适用于 C 语言风格的内存管理。new
和delete
:new
在分配内存后调用构造函数,delete
在释放内存前调用析构函数,适用于需要对象初始化和清理的场景。
4. 内存分配失败处理
malloc
: 内存分配失败时返回NULL
,需要显式检查。new
: 内存分配失败时抛出std::bad_alloc
异常。
5. 自定义操作符
new
和delete
: 可以重载自定义的new
和delete
操作符来实现特定的内存分配行为。
6. 适用范围
malloc
和free
: 主要用于 C 语言,也可以在 C++ 中使用,但不推荐用于需要对象初始化的场景。new
和delete
: 专为 C++ 设计,推荐用于分配和释放 C++ 对象。
7. 内存分配地址
-
malloc
:是在堆上分配的,如果分配的内存小于128k一般是在内存池中取用。如果大于128k则通常会使用 mmap 系统调用直接从操作系统请求内存。mmap 会映射一个匿名内存区域到进程的地址空间,并返回该区域的地址。这种方法的优点是大块内存可以独立管理和释放,不会影响到常规的内存池。 -
new
: 是在free sotre上分配内存-
调用 operator new 分配内存:operator new 是一个内置的或用户自定义的函数,用于从自由存储区分配足够的内存。
标准库提供了默认实现的 operator new,通常会调用底层的内存分配函数(如 malloc)来分配内存。
operator new 可能会抛出 std::bad_alloc 异常,如果内存分配失败。
调用对象的构造函数: -
在成功分配内存后,new 运算符会在分配的内存地址上调用对象的构造函数。
这一步骤确保对象被正确地初始化。
返回对象的指针: -
构造函数调用完成后,new 运算符返回指向新分配和构造的对象的指针。
-
示例对比
malloc
和 free
示例
#include <cstdlib> // 包含 malloc 和 free 的头文件
#include <iostream>struct MyStruct {int x;MyStruct() : x(10) {} // 自定义构造函数
};int main() {MyStruct* p = (MyStruct*)malloc(sizeof(MyStruct)); // 只分配内存,不调用构造函数if (p == nullptr) {std::cerr << "Memory allocation failed\n";return 1;}p->x = 20; // 需要手动初始化std::cout << "MyStruct.x = " << p->x << std::endl;free(p); // 只释放内存,不调用析构函数return 0;
}
new
和 delete
示例
#include <iostream>struct MyStruct {int x;MyStruct() : x(10) {} // 自定义构造函数~MyStruct() { std::cout << "Destructor called\n"; } // 自定义析构函数
};int main() {MyStruct* p = new MyStruct; // 分配内存并调用构造函数std::cout << "MyStruct.x = " << p->x << std::endl;delete p; // 调用析构函数并释放内存return 0;
}
总结来说,malloc
/free
主要用于 C 风格的内存管理,而 new
/delete
适用于 C++,因为它们不仅分配和释放内存,还能处理对象的构造和析构。