malloc,new 及free,delete的区别和联系

本文介绍了内存动态分配的三种主要方式,包括静态存储区分配、栈上创建和堆上分配,并详细探讨了使用new和malloc进行内存分配的方法及注意事项。此外,还列举了一些常见的内存使用错误及其解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存动态分配方法

1.内存分配方式(三种)
(1)静态存储区分配,内存在程序编译时就分配好,在程序整个运行时期都存在。例如全局变量,static变量
(2)栈上创建,函数局部变量都可以在栈上创建,函数执行结束时被自动释放。效率高,但分配内容有限。
(3)堆上分配,程序运行时用malloc或new申请内存,程序员负责在何时用free或delete释放内存。

2.内存使用错误
(1)内存分配未成功,却使用了它。
解决方法:在使用内存之前检查指针是否为NULL。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。
(2) 内存分配虽然成功,但是尚未初始化就引用它。
解决方法:创建数组,要赋初值,及时赋零值。
(3)内存分配成功并且已经初始化,但操作越过了内存的边界。
(4)忘记了释放内存,造成内存泄露。
(5)释放了内存却继续使用它。

总结:

【规则1】用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存
【规则2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作
【规则4】动态内存的申请与释放必须配对,防止内存泄漏。
【规则5】用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”

一 . new

new和delete运算符用于动态分配和撤销内存的运算符

new的用法:

1.开辟单变量地址空间
1)new int; //开辟一个存放数组的存储空间,返回一个指向该存储空间的地址.int *a = new
int 即为将一个int类型的地址赋值给整型指针a.
2)int *a = new int(5) 作用同上,但是同时将整数赋值为5
2. 开辟数组空间
一维: int *a = new int[100];开辟一个大小为100的整型数组空间
一般用法: new 类型 [初值]

delete用法:
1. int *a = new int;
delete a; //释放单个int的空间
2.int *a = new int[5];
delete [] a; //释放int数组空间
要访问new所开辟的结构体空间,无法直接通过变量名进行,只能通过赋值的指针进行访问.
用new和delete可以动态开辟,撤销地址空间.在编程序时,若用完一个变量(一般是暂时存储的数组),
下次需要再用,但却又想省去重新初始化的功夫,可以在每次开始使用时开辟一个空间,在用完后撤销它.

二 . malloc

   原型:extern void *malloc(unsigned int num_bytes);

  用法:#i nclude

malloc()函数的工作机制:

malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc
函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大
小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并
将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到
最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以
满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们
进行整理,将相邻的小空闲块合并成较大的内存块。

1.malloc(realloc)/free
(1)malloc/free是(libc.soc语言的库函数)。
(2)free释放内存时,不区分单个元素内存和数组分配。
(3)malloc开辟内存失败,返回值和NULL进行判断。
2.new/delete
(1)new/delete属于运算符不属于函数。
(2)delete释放内存时,区分单个元素内存和数组分配。

malloc和new的区别

1.malloc是函数,而new是运算符。
2.malloc结果要进行类型强转,new不用。
3.malloc只能分配内存,new还可以初始化。
4.malloc开辟内存失败返回NULL指针,new发出bad——alloc异常。(try catch)
5.new底层调用的是malloc。

free和delete的区别

1.delete底层调用的是free。
2.delete释放数组内存时,delete和指针之间要加 [ ](用来区分单个元素内存和数组内存)。

拓展问题:以下两组的区别

int *P1=new int[3];//在堆上开辟空间,不初始化
int *P2=new int3;//除在堆上开辟空间之外,还初始化为一个整型数组,之中的元素分别为0;

<think>好的,我现在要回答用户关于C++中newmallocdeletefree区别的问题。首先,我需要回忆自己之前学过的相关知识,确保信息准确。然后,按照用户的要求,结构要清晰,分步骤解释,同时引用提供的资料中的相关内容。 首先,newmalloc都是用于动态内存分配,但它们在C++中有很多不同。我应该从以下几个方面来比较:语法、构造函数调用、类型安全、内存大小计算、错误处理、重载可能性以及内存来源等方面。同样,deletefree区别也需要涵盖析构函数调用内存释放的细节。 接下来,我需要检查用户提供的引用内容,看看是否有可以引用的地方。引用[1]中提到了使用malloc_allocator的vector,这可能与内存分配器有关,但不确定是否直接相关。引用[2]是关于宏扩展编译的示例,可能内存管理关系不大,但需要留意是否有相关内容。看起来这两个引用可能不是直接回答问题的关键,但或许可以在讨论底层实现时提及。 然后,我需要确保使用正确的中文表达,行内公式用$...$,独立公式用$$...$$。不过在这个问题中,可能涉及到的数学公式不多,但如果有提到内存分配的大小计算,可能需要用到。比如,使用malloc时计算数组大小的例子,可以写成$sizeof(int) * n$。 另外,用户要求生成相关问题,我需要根据回答的内容,提出几个相关的问题,比如内存泄漏处理、异常安全、placement new使用等。 现在,开始组织内容: 1. 语法差异:new是运算符,malloc是函数。例如,int *p = new int; vs int *p = (int*)malloc(sizeof(int)); 2. 构造函数析构函数:new会调用构造函数,delete调用析构函数,而malloc/free不会。这一点很重要,特别是对于带有资源管理的对象,比如类中有文件句柄或锁的情况。 3. 类型安全:new返回正确类型的指针,不需要强制转换;malloc返回void*,需要显式转换。 4. 内存大小计算:malloc需要手动计算字节数,比如分配10个int:malloc(sizeof(int)*10),而new直接写new int[10]。 5. 错误处理:new在分配失败时抛出std::bad_alloc异常,而malloc返回NULL,需要检查返回值。 6. 重载:可以重载类的operator newoperator delete,而malloc/free不能重载。 7. 内存来源:new从自由存储区分配,malloc从堆分配,但具体实现可能相关,这里可能需要引用[1]提到的分配器,比如malloc_allocator,说明不同分配器的使用情况。 关于引用部分,引用[1]中的std::vector使用malloc_allocator,可能说明C++中容器可以自定义分配器,而默认情况下vector使用new/delete,但用户可以通过分配器选择使用malloc/free。这一点可以作为扩展内容提及,说明在特定情况下,用户可能需要替换默认的内存管理方式。 引用[2]中的例子涉及预处理编译过程,可能内存管理关系不大,暂时不考虑引用。 在回答时,需要确保每个区别点清晰,并且举例说明。例如,在构造函数调用方面,可以举一个类的例子,用new创建对象时会调用构造函数,而malloc不会,可能导致对象状态不正确。 最后,生成相关问题,比如newmalloc的底层实现差异,如何避免内存泄漏,智能指针如何管理内存等。 需要避免错误,比如不要混淆自由存储区(free store)堆(heap),虽然有时实现可能将两者视为同一区域,但标准中它们是不同的概念。另外,确保提到deletefree不能混用,否则可能导致未定义行为,比如用free释放new分配的内存,或者用delete释放malloc分配的内存。 总结一下,回答的结构应该是先概述主要区别,然后分点详细说明,每个点举例并必要时引用资料,最后提出相关问题。</think>在C++中,`new`/`delete`与`malloc`/`free`均用于动态内存管理,但存在以下核心区别: --- ### 1. **语法与类型安全** - **`new`/`delete`** 是运算符,直接关联类型: ```cpp int* p = new int(5); // 分配并初始化int为5 delete p; // 释放内存 ``` - 类型安全:`new`返回正确类型的指针,无需强制转换。 - **`malloc`/`free`** 是函数,需手动计算字节数并类型转换: ```cpp int* p = (int*)malloc(sizeof(int)); // 显式转换且未初始化 free(p); ``` --- ### 2. **构造与析构函数** - **`new`** 调用构造函数: ```cpp class MyClass { /* 构造函数成员 */ }; MyClass* obj = new MyClass(); // 调用构造函数 ``` - **`delete`** 调用析构函数: ```cpp delete obj; // 调用析构函数后释放内存 ``` - **`malloc`/`free`** 仅分配/释放内存,**不调用构造/析构函数**,可能导致资源泄漏(如未关闭文件)[^1]。 --- ### 3. **内存分配失败处理** - **`new`** 失败时抛出`std::bad_alloc`异常,需用`try-catch`捕获: ```cpp try { int* p = new int[10000000000]; } catch (const std::bad_alloc& e) { // 处理异常 } ``` - **`malloc`** 失败返回`NULL`,需显式检查: ```cpp int* p = (int*)malloc(10000000000); if (!p) { /* 处理错误 */ } ``` --- ### 4. **内存大小计算** - **`malloc`** 需手动计算字节数: ```cpp int* arr = (int*)malloc(10 * sizeof(int)); // $10 \times \text{sizeof(int)}$ ``` - **`new`** 自动推导类型大小: ```cpp int* arr = new int[10]; // 直接指定元素数量 ``` --- ### 5. **重载与扩展性** - **`new`/`delete`** 可重载,支持定制内存管理策略: ```cpp void* operator new(size_t size) { /* 自定义逻辑 */ } ``` - **`malloc`/`free`** 不可重载,行为固定。 --- ### 6. **内存来源** - **`new`** 从**自由存储区(free store)**分配内存,具体实现可能依赖编译器。 - **`malloc`** 从**堆(heap)**分配,属于C运行时库管理。 - C++容器(如`std::vector`)可通过分配器(如`malloc_allocator`)选择底层内存来源。 --- ### 错误使用示例 - **混用导致未定义行为**: ```cpp int* p = new int; free(p); // 错误!应使用delete int* q = (int*)malloc(sizeof(int)); delete q; // 错误!应使用free ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值