欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

new与malloc的区别

程序员文章站 2022-05-31 09:00:35
...

一,malloc与free函数

1,malloc()函数

函数原型:void  *malloc(int  size)

函数功能:malloc的全称是memory allocation,中文是动态内存分配。malloc向系统申请size个字节大小的内存空间,函数的返回值类型是void  *类型。void  *表示未确定类型的指针,C/C++规定void  *类型指针可以转换成任何其他类型的指针。void  *表示未确定类型的指针,是说申请内存空间时,还不知道用户要用这块内存空间存储什么类型的数据。


2,free()函数

函数原型:void  free(void  *p)

函数功能:释放掉之前使用malloc分配的内存空间。


3,注意事项

a,申请内存空间之后,必须检查是否分配成功。

b,当不需要申请的内存时,记得及时释放掉。释放后应该把指向这块内存的指针设置为NULL,防止后面的程序不小心用到它。

c,malloc与free应该配对使用。


4,malloc是从什么地方获取的内存空间?

从堆里获取的内存空间,操作系统有一个记录空闲内存地址的链表。当系统收到内存申请时,就会遍历该链表,寻找第一个空间大于所申请的内存的节点,然后把这个节点从链表中删除,并将该节点的内存分配给申请者。


二,new运算符

1,使用new动态分配内存

int *p = new int;  //动态分配内存
int *p = new int(10);  //分配内存,并对内存进行初始化


2,使用delete释放分配的内存

delete p;  //释放单个对象
delete [] p;  //释放对象数组


3,new分配失败

new分配失败时,会抛出bad_alloc异常


4,注意事项

new与delete、new []与delete []要配对使用,不然可能会导致内存泄露。使用delete的最大问题在于:即将被删除的内存里有多少个对象?这个问题的答案决定了有多少个析构函数必须被调用。上面的这个问题也可理解为:即将被删除的那个指针,所指的是单一对象还是对象数组。如果使用delete时不加中括号,此时delete便认定要删除的是一个单独的对象,如果使用delete时加上中括号,此时delete便认定要删除的是一个对象数组


三,new与malloc的区别

1,是否需要指定要分配的内存的大小

new返回指定类型的指针,并自动计算大小,例如:下面的new返回的指针类型为int *,分配的内存空间的大小为sizeof(int)。

int *p = new int;

 

malloc则必须由我们计算分配的字节数,并且在返回后还要把指针强制转换为实际的类型

int *p = (int *)malloc(sizeof(int));


2,是否会对分配的内存进行初始化

malloc只负责分配内存,并不能对分配的内存进行初始化,但是new可以对分配的内存进行初始化。

#include <iostream>
#include <stdlib.h>
using namespace std;

class A{
public:
    A(){cout<<"A"<<endl;}
};


int main(){
    A *p1 = new A;
    A *p2 = (A *)malloc(sizeof(A));
    return 0;
}

输出结果

A

Process returned 0 (0x0)   execution time : 0.006 s
Press any key to continue.

程序分析

由程序的输出结果可以看出,new会分配内存,并调用类的构造函数创建对象,而malloc只是分配内存,不调用类的构造函数初始化对象。


四,有了malloc/free为什么还要使用new/delete?

1,对于自定义的class类型,malloc无法满足动态创建对象的要求。对象在创建的同时要自动执行构造函数,对象的生命周期结束时要自动调用析构函数。由于malloc/free是库函数而不是运算符,不在编译器的控制权限之内,不够把执行构造函数与析构函数的任务强加于malloc/free。因此,C++提供了new运算符来完成内存的动态分配与初始化工作,delete来完成内存的清除与释放工作。

2,既然new/delete的功能已经覆盖malloc/free,C++为什么不淘汰掉malloc/free?这是因为C++程序要经常调用C函数,而C函数只能使用malloc/free来动态管理内存。

3,如果使用free释放使用new创建的对象,那么该对象因无法执行析构函数而可能导致程序出错。如果使用delete释放malloc分配的内存,结果也会导致程序出错,所以new/delete,malloc/free应该配对使用。