new和malloc以及delete和free的区别

malloc

malloc是C语言中的一个函数,作用是动态开辟一块连续的内存(初始值为随机值)。
原型为:
void *malloc( size_t size );//size_t为无符号整型,size为开辟的字节数。使用时需要指定数据类型。
包含的头文件是stdlib.h或malloc.h.
内存分配位置:堆中动态分配的内存。
具体分配过程:由程序向操作系统申请,操作系统遍历空闲结点链表,将第一个大于申请空间的堆结点分配给程序,然后将空闲结点链表中此节点删掉。
成功分配:返回值为指向被分配内存的指针。
失败分配:返回值为空NULL。
返回类型:void* (未确定类型的指针)。
void*类型可以通过强制类型转换转换为任意其他类型(因为用户存储数据类型未知,由用户决定数据类型)。
内存块释放:free()函数 将内存还给程序或操作系统。
注意:malloc与free都属于c/c++标准库函数,在使用时应该配对 申请之后不释放就会有可能发生内存泄漏。
使用free时需要检查指针是否为空。

delete与free的不同之处在于,用delete释放内存之前会先调用析构函数。delete与free在使用完成后注意将指针置为NULL,否则会形成悬空指针(指针所指内存已被释放,仍指向该内存),造成错误。

new

new 是c++中的运算符。
在使用:new时不止分配内存,还会进行初始化,执行相应构造函数,初始化时需要指定数据类型。
内存分配位置:自由存储区为对象分配内存。
使用时:无需引入头文件,new是保留字。
new 和 delete 是配对使用的。
new 可以看做是malloc 加 构造函数的执行,就是new更高级一些。

问题:用一个3*4的二维数组的动态开辟和内存释放:

//动态开辟
int **p = new int*[3];
for (int i = 0;  i < 3; ++i)
{
    p[i] = new int[4];
}
//释放
for (int i = 0;  i < 3; ++i)
{
    delete []p[i];
}
delete []p;

//这样开辟是错误的

int **p = new int[3][4];

当用new[]时,delete时,应为delete[].

new有四种用法,如下:

  1. 普通(默认)new:
int *p = new int(10);//10表示初始值
/*
if(p == NULL)//开辟失败不会返回NULL,所以这样做是错误的。
{
    return -1;
}
*/
//若开辟失败会抛出一个异常:throw bad_alloc("");
try
{
    int *p = new int(10);
}
catch (const bad_alloc &err)//可以通过捕获异常来解决
{
}

2、不抛出异常的new:
形如:int *p = new (nothrow) int(10);
不抛出异常的new可以通过返回值是否为空来判断是否开辟成功。

3、在堆上开辟常量:

例如:

const int *p = new const int(4);
const int *q = new const int[10];
//这样做没有什么意义,因为不能给*p和*q赋值

4、定位new(placement new):
定位new不真正在堆上开辟空间,是在已经存在的内存上使用空间。

char buffer[1024] = {0};
char *p = new (buffer) char[100];

利用定位new可以实现简单的内存池。

<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 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值