free/delete 释放的内存大小?

本文深入探讨了C/C++中malloc/free及new/delete如何管理内存。解释了在分配内存时,系统如何记录分配大小,并在释放内存时利用这些信息确保正确释放。此外还引用了StackOverflow上的一段讨论,强调了free无需用户提供分配大小的重要性。

在使用c或者c++的时候我们经常用到malloc/free和new/delete,在使用malloc申请内存的时候我们给定了需要申请的内存大小,但是在free或者delete的时候并不需要提供这个大小,那么程序是怎么实现准确无误的释放内存的呢?

实际上,在申请内存的时候,申请到的地址会比你实际的地址大一点点,他包含了一个存有申请空间大小的结构体。

比如你申请了20byte的空间,实际上系统申请了48bytes的block

16-byte header containing size, special marker, checksum, pointers to next/previous block and so on.
32 bytes data area (your 20 bytes padded out to a multiple of 16))
这样在free的时候就不需要提供任何其他的信息,可以正确的释放内存

这里有个在stackoverflow.com上的提问,可以参考How does free know how much to free?

stackoverflow 回复
Can you imagine the horror if free() required the programmer to accurately report how big the malloc() block was? The memory leaks are bad enough as it is. – MusiGenesis
释义:如果free()需要程序员准确地报告这个malloc()块有多大,你能想象这个恐怖吗?内存泄漏已经足够糟糕了。

转载网址

free/delete 怎么知道有多少内存要释放

<think>我们正在讨论C++中new/delete与malloc/free的区别以及为什么需要new/delete。首先,需要明确的是,newdelete是C++的运算符,而mallocfree是C标准库函数。主要区别如下:1.类型安全:new在分配内存时返回指定类型的指针,而malloc返回void*,需要显式类型转换。2.构造与析构:new会调用对象的构造函数,delete会调用析构函数。而malloc/free只负责内存分配释放,不调用构造析构。3.内存分配失败处理:new在分配失败时会抛出std::bad_alloc异常,而malloc失败时返回NULL。4.内存大小计算:使用new时编译器会自动计算所需内存大小,而malloc需要手动计算(如使用sizeof)。5.重载:C++允许重载newdelete运算符,而malloc/free不能重载。6.初始化:new可以初始化对象(如使用newint(5)初始化整数为5),而malloc分配的内存是未初始化的。7.重新分配:malloc可以使用realloc重新调整已分配内存的大小,而new没有类似的机制(需要手动实现)。为什么需要new/delete?在C++中,对象不仅有内存分配的需求,还有构造析构的需求。使用new/delete可以确保在分配内存的同时调用构造函数进行初始化,在释放内存之前调用析构函数进行清理。这是C++面向对象特性的重要支持。下面我们详细说明:一、类型安全使用new分配内存:int*p=newint;//返回int*类型使用malloc:int*p=(int*)malloc(sizeof(int));//需要强制转换,且容易遗漏sizeof二、构造析构考虑一个类:classMyClass{public:MyClass(){/*构造函数*/}~MyClass(){/*析构函数*/}};使用new/delete:MyClass*obj=newMyClass;//调用构造函数deleteobj;//调用析构函数使用malloc/free:MyClass*obj=(MyClass*)malloc(sizeof(MyClass));//不调用构造函数free(obj);//不调用析构函数这样,如果类中有动态分配的内存或资源(如文件句柄),使用malloc/free会导致资源泄漏,因为构造函数析构函数没有被调用。三、异常处理使用new时,如果内存不足,会抛出异常,我们可以用try-catch捕获。而malloc需要检查返回值。四、自定义管理new/delete可以重载,从而允许自定义内存管理策略(如使用内存池)。五、数组分配new支持数组分配,并会为每个元素调用构造函数:MyClass*arr=newMyClass[10];使用delete[]释放,会为每个元素调用析构函数。malloc则无法做到这一点。六、初始化对于内置类型,new可以初始化:int*p=newint(10);//初始化为10malloc分配的内存需要手动初始化。因此,在C++中,对于类类型的对象,必须使用new/delete。对于非类类型(如基本类型或POD结构),虽然可以使用malloc/free,但为了代码的一致性安全性,通常也推荐使用new/delete。注意:new/deletemalloc/free不能混用。例如,用malloc分配的内存不能用delete释放,用new分配的内存也不能用free释放,否则可能导致未定义行为。总结:new/delete是C++中管理动态内存对象生命周期的运算符,它们提供了类型安全、自动构造析构、异常安全等特性,是C++面向对象编程不可或缺的部分。下面生成相关问题:</think>### C++中`new/delete`与`malloc/free`的区别及必要性 #### 1. **核心区别** | **特性** | **`new/delete`** | **`malloc/free`** | |----------------------|--------------------------------------|-----------------------------------| | **语言归属** | C++运算符 | C标准库函数 | | **类型安全** | 自动推导类型(无需`sizeof`或强制转换)| 返回`void*`(需手动类型转换) | | **构造/析构函数** | ✅ 调用构造函数析构函数 | ❌ 仅分配/释放内存 | | **内存初始化** | ✅ 可初始化(如`new int(5)`) | ❌ 分配未初始化的内存 | | **失败处理** | 抛出`std::bad_alloc`异常 | 返回`NULL` | | **重载支持** | ✅ 可重载运算符 | ❌ 不可重载 | | **内存大小计算** | 编译器自动计算 | 需手动指定(如`sizeof(int)*n`) | #### 2. **必要性分析** - **对象生命周期管理** `new`在分配内存后调用构造函数初始化对象,`delete`在释放内存前调用析构函数清理资源(如释放内部指针、关闭文件等)。 而`malloc/free`仅操作原始内存,不涉及对象构造/析构,**易导致资源泄漏**。 **示例**: ```cpp class Resource { int* data; public: Resource() { data = new int[100]; } // 构造函数分配资源 ~Resource() { delete[] data; } // 析构函数释放资源 }; // 错误用法:malloc不会调用构造函数 → data未初始化 Resource* r1 = (Resource*)malloc(sizeof(Resource)); free(r1); // 析构函数未被调用 → 内存泄漏! // 正确用法:new调用构造函数,delete调用析构函数 Resource* r2 = new Resource(); delete r2; // 安全释放 ``` - **类型安全** `new`返回精确类型指针,避免类型错误: ```cpp int* p1 = new int; // 类型正确 int* p2 = (int*)malloc(sizeof(int)); // 需手动转换 ``` - **异常安全** `new`的异常机制符合C++ RAII(资源获取即初始化)原则,可与`try-catch`集成: ```cpp try { int* p = new int[10000000000]; // 失败时抛出异常 } catch (const std::bad_alloc& e) { // 异常处理 } ``` - **与C++特性集成** `new/delete`支持**数组分配**(`new[]/delete[]`)、**自定义分配器**、**放置`new`** 等高级特性,而`malloc/free`无法实现。 #### 3. **混合使用的风险** **绝对禁止混用**! - `malloc`分配 + `delete`释放 → **未调用析构函数** → 资源泄漏 - `new`分配 + `free`释放 → **未调用析构函数** → 资源泄漏 + **未定义行为** ```cpp std::string* s = new std::string("Hello"); free(s); // 错误!未调用~string() → 内部动态内存泄漏 ``` #### 4. **何时使用`malloc/free`?** - 仅需处理**原始内存**(如底层内存池) - 与C语言库交互时(如`fopen`返回的`FILE*`需用`free`释放) - **POD类型(Plain Old Data)** 且无构造/析构需求时(但`new/delete`仍更安全) > 总结:`new/delete`是C++面向对象内存管理的核心机制,提供类型安全、完整的对象生命周期管理及异常安全。在C++代码中应优先使用`new/delete`,仅在特定场景(如与C交互)才考虑`malloc/free`[^1]。 --- ### 相关问题 1. 如何为自定义类重载`new``delete`运算符? 2. C++中`delete``delete[]`的区别是什么?混用会导致什么问题? 3. 什么是**放置`new`(placement new)**?它有哪些应用场景? 4. C++11的智能指针(如`unique_ptr`、`shared_ptr`)如何替代`new/delete`? [^1]: C开发者通常因模板函数重载对C++持谨慎态度,更倾向于使用指针运算过程式编程(如`malloc/free`),但C++的`new/delete`为面向对象提供了必要的安全保障。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值