qidao123.com技术社区-IT企服评测·应用市场
标题:
C++ new/delete和malloc/free的区别(面试总结)
[打印本页]
作者:
风雨同行
时间:
2025-4-20 07:46
标题:
C++ new/delete和malloc/free的区别(面试总结)
性质
malloc/free 是C语言中的标准库函数,用于动态内存管理;
new/delete 是C++中的操作符,底层调用了 malloc/free。
分配方式
malloc、free
int* arr = (int*)malloc(10 * sizeof(int)); // 分配
free(arr); // 释放
复制代码
代码含义:
动态分配了一块连续内存,用于存储10个 int 范例的整数;
10 * sizeof(int):分配巨细为 10 * 4 ( int范例字节数) = 40字节;
(int*)malloc : malloc返回范例是void*,通过(int*)逼迫转换成int*范例指针;
free(arr): 释放malloc分配的内存,arr变成悬空指针,释放后的内存不可以再访问。
new、delete
int* val = new int(42); // 分配并初始化
delete val; // 释放
复制代码
代码含义:
new int(42):主动计算范例巨细(不必要sizeof),分配巨细为 42 * 4 = 168字节;
返回 int*范例的指针;
特性malloc/freenew/delete范例安全返回void*,需逼迫转换返回该范例对象的指针内存巨细手动计算主动分配
内存区域
malloc函数从堆上分配内存,而new在自由存储区(free store)上分配内存。
无论是使用 malloc 还是 new,内存分配初始都在虚拟内存上,物理内存的分配是延迟的(由操作体系的按需分页机制控制)
如果直接使用物理内存,内存管理会变得复杂低效;
虚拟内存是操作体系为每个进程提供的抽象内存空间,独立于物理内存,进程看到的地点是虚拟地点,必要通过硬件和页表来转换为物理地点;
1.每个进程拥有独立的虚拟地点空间,互不干扰,
2.虚拟地点空间连续,物理内存是可以离散的,
3.通过分页和交换技术,虚拟内存可以大于物理内存,
4.物理内存分配是延迟的,只有当程序首次访问这块内存,内核才会分配物理内存。
malloc 和 new 只操作虚拟内存,物理内存的分配由操作体系在首次访问内存时,通过缺页异常触发。
malloc 举动
仅分配虚拟内存,不触发物理内存分配,首次访问内存(写入或读取)时才分配物理内存。
int* arr = (int*)malloc(1024 * sizeof(int)); // 仅虚拟内存分配
arr[0] = 10; // 首次写入触发缺页异常,分配物理内存
复制代码
new 举动
为对象分配虚拟内存地点,并调用构造函数,构造函数初始化内容可能隐含首次内存访问,从而间接触发物理分配。
class MyClass {
public:
int data;
MyClass() { data = 42; } // 写入data操作触发缺页异常,分配物理内存
};
MyClass* obj = new MyClass(); // 物理内存在构造函数执行时分配
复制代码
class MyClass {
public:
int data; // 未初始化
MyClass() {} // 无内存访问
};
MyClass* obj = new MyClass(); // 物理内存未分配,直到后续访问obj->data
复制代码
底层实现
malloc/free
仅管理内存,不涉及构造/析构函数的调用
分配空间重要有两种方式(brk,mmap)
小内存分配(通常小于128KB):
在堆上分配虚拟连续的内存区域,释放时,内存块被标志为空闲,并不会立刻归还给操作体系,而是加入空闲链表(供后续 malloc 重用),分配速度快,但是会导致内存碎片化。
大内存分配(大于128KB):
使用 mmap 直接在进程的虚拟地点空间中常见独立的内存映射,释放时整个映射区立即归还给体系,避免了碎片化,但是开销比力大。
new/delete
new 和 delete 都是 C++ 的关键字,new 的举动分为 内存分配 和 对象构造 两部,delete 的举动分为 对象析构 和 内存释放 两步。
new:
1.operate new(起首调用全局的 operator new 函数分配内存,默认实现基于 malloc);
2.申请充足的空间;
3.调用构造函数,初始化变量。
delete:
1.调用析构函数;
2.operate delete(默认实现调用 free);
3.释放空间。
失败处置惩罚
malloc 在内存分配失败时返回 NULL,需手动查抄返回值。
必须显式查抄返回值,并且无异常机制,完全依赖流程控制。
new 在内存分配失败时抛出异常(std::bad_alloc)
异常机制主动流传错误,适合面向对象和复杂场景,如果构造函数抛出异常,已分配的内存会被主动释放。
重载能力
malloc/free
是C语言标准库的预定义函数,在链接时绑定到标准库实现,没法通过语言特性直接替换它们。
而
new/delete
可以通过重载 operator new 和 operator delete 来自定义动态内存分配和释放的举动。
class MyClass {
public:
// 重载类的数组 new[]
static void* operator new[](size_t size) {
std::cout << "类内 new[]: 分配数组 " << size << " 字节\n";
void* p = malloc(size);
if (!p) throw std::bad_alloc();
return p;
}
// 重载类的数组 delete[]
static void operator delete[](void* p) noexcept {
std::cout << "类内 delete[]: 释放数组内存\n";
free(p);
}
};
int main() {
MyClass* arr = new MyClass[5]; // 触发类的 operator new[]
delete[] arr; // 触发类的 operator delete[]
return 0;
}
复制代码
小结
本文重要从分配方式、内存存储、失败处置惩罚以及重载能力几个方面介绍了 malloc/free 和 new/delete 的区别,希望能对你有资助!
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4