您的位置:首页 > 其它

malloc/free与new/delete的区别

2017-03-30 11:28 162 查看
一、malloc/free:

1、malloc的全称为memory allocation,中文解释为动态内存分配。

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

在c语言中,包含在#include<stdlib.h>或者#include<malloc.h>;
2、函数声明:void *malloc(size_t size)

void* 表示未确定的数据类型指针,void*可以指向任意数据类型。更明确地说在申请这块内存空间之前并不知道用户用这块内存来存储什么类型的数据。
3、返回值
如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则失败则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象

4、注意
1)在申请空间之后,我们一定要检验是否内存分配成功;
2)当不再使用开辟的内存时,一定要记着用free()释放,释放后将指向此空间的指针置NULL,防止后面万一不 小心使用该指针;
3)malloc与free一定要配对使用,否则会出现问题,如果申请了空间但未释放这就会造成内存泄漏,而释放只能进行一次,释放多次会出现错误;(释放空指针例外,释放空指针等于什么也没做,所以释放多次也无所谓)
4)虽然void*可以指向任意类型的指针,但是最好在使用前,将其强转成指定类型,这样可以更好的避过有些编译器的优化;
5、malloc在哪里开辟空间?

从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。


二、new/delete
1、在c++中,用new/delete来动态开辟和释放数组或单个对象;
在动态开辟内存时,只需为其指定数据类型,并不需要为其命名;new表达式返回指向该新创建对象的指针,我们可以通过指针来访问此对象;
int* pi = new int;

这个new表达式在堆区中分配创建了一个整型对象,并返回此对象的地址,并用该地址初始化指针pi 。


2、动态创建类型的初始化

动态开辟的对象可以通过初始化变量的方式初始化;

int *pi = new int(100);//pi指向的对象初始化为100
string *pi = new string(10,'s');//pi指向的对象初始化为ssssssssss
如果没有显式的初始化,对于类类型,则会调用对象默认的构造函数;对于内置类型,则没有初始化;

int *pi = new int();//pi指向的对象初始化为0
string *pi = new string();//初始化为一个空字符串
int *pi = new int;//指向一个未被初始化的int


3、释放问题

delete pi 释放对象类型

delete [] 释放数组类型

delete与new要匹配使用,否则会出现意想不到的错误;
三、new/delete与malloc/free的不同

1、new 返回指定类型的指针,并且自动计算所需内存大小;malloc则需要我们显式计算大小,并且在返回时强转成我们所需要的类型;

例:
int *pi = new int;//返回int*指针,分配sizeof(int)大小
int *pi = new int[100]; //返回int*指针,分配sizeof(int)*100的大小
int *pi = (int*)malloc(sizeof(int));
int *pi = (int*)malloc(sizeof(int)*100);
2、malloc只进行内存分配,不进行初始化,在分配完内存之后,其值在内存中是随机的;

3、对于非内置类型而言,malloc/free不能满足其对象管理。对象在创建时要自动调用构造函数,在释放时,需要调用析构函数,而malloc/free是库函数,不在编译器的控制权限之内,从而使用new/delete来进行操作;注意:new/delete不是库函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内存分配 malloc