malloc和new的区别

来源:互联网 发布:ubuntu server安装桌面 编辑:程序博客网 时间:2024/06/11 20:44

前段看书的时候看到了new和delete,是关于C++的动态内存开辟,而在以前的C语言的学习中学到过malloc和free,也是关于动态内存开辟的,今天想就C语言和C++ 中的动态内存有何差异来做个学习和总结。

malloc,calloc,realloc

在C语言中,动态内存的关键字有三个,分别是:

1.malloc 其形式为

void* malloc(int size);

可以看到其返回值为void*,表示为未确定类型的指针,可以转换为任意类型指针,只有一个参数,就是开辟空间元素的大小,malloc不为开辟的空间进行初始化。在每个malloc后面都不能忘记使用free对开辟的空间进行释放

2.calloc 其形式为

void* calloc(n,int size);

返回值也是void*,n为申请空间的元素的个数,size为元素的大小,calloc会对申请的空间进行初始化,将其初始化为0。

3.realloc 其形式为

void* realloc(void* p,int size);

返回值同样是void*,作用是给一个已经分配的地址的指针重新分配空间,p为原空间地址,size为重新申请的长度,realloc可以对给定的指针所指的空间进行扩大或者缩小,原有内存的中内容将保持不变.当然,对于缩小,缩小的那一部分的内容会丢失.

realloc并不保证调整后的内存空间和原来的内存空间保持同一内存地址.realloc返回的指针很可能指向一个新的地址.realloc是从堆上分配内存的.当扩大一块内存空间时,realloc直接从堆上现存的数据后面的那些字节中获得附加的字节,如果满足,就直接添加;

int main(){    char *p, *q;    p = (char *)malloc(10);    q = p;    p = (char *)realloc(p, 10);    printf("p=0x%x", p);    printf("\n");    printf("q=0x%x", q);    system("pause");    return 0;}

这里写图片描述
如果数据后面的字节不够,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上.数据可能被移动.

int main(){    char *p, *q;    p = (char *)malloc(10);    q = p;    p = (char *)realloc(p, 1000);    printf("p=0x%x\n", p);    printf("q=0x%x\n", q);    system("pause");    return 0;}

这里写图片描述

new/delet

new

在定义变量时,必须指定数据类型和名字,但是动态创建对象时只需要指定其数据类型,不必命名

int i;int *p = new int;int i(10);int * p1 = new int(10);string s(10, '9');string* ps = new string(10, '9');

因为new 内置了sizeof、类型转换和类型安全检查功能。对于非内部数据类型的对象而言,new 在创建动态对象的同时完成了初始化工作

//如果提供了初值,new表达式分配内存后就用给定的初值初始化该内存空间,int * p1 = new int(10);string* ps = new string(10, '9');//如果不提供显示初始化,其初始化方式与函数的内定义初始化方式相同。类类型的对象,使用该类的默认构造函数初始化,内置类型对象无初始化。string *ps = new string;int * pi = new int;//对于内置类型和没有定义默认构造函数的类型,初始化方式有区别int * p1 = new int; //int型变量没有初始化int * p2 = new int();//int型变量被初始化为0

delete

动态创建的对象用完之后,必须显示的将对象所占用的内存返回给自由存储区,在C++中我们使用delete来释放指针所指向的空间。

int i;int * pi = new int;delete pi;

delete表达式释放指针指向的地址空间,如果指针指向的不是new分配的内存地址,则使用delete是不合法的。

执行完该语句后,p变成了不确定的指针,在很多机器上,尽管p值没有明确定义,但仍然存放了它之前所指对象的地址,然后p所指向的内存已经被释放了,所以p不再有效。此时,该指针变成了悬垂指针(悬垂指针指向曾经存放对象的内存,但该对象已经不存在了),一旦删除了指针所指的对象,立即将指针置为0,这样就非常清楚的指明指针不再指向任何对象。

//零值指针:int *ip=0;

malloc和new的区别

1.malloc/free是标准库函数,而new/delete是运算符。

(1).为什么有了malloc和free还要使用new和delete?

对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。

(2).new和delete的功能已经覆盖了malloc和free,那为什么还要使用malloc和free呢?

因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete、malloc/free必须配对使用。

2.new返回指定类型的指针,并且可以自动计算所需要大小。而malloc则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。

//newint * p = new int;int * p1 = new int [100];//mallocint * p = (int*)malloc(sizeof(int));
原创粉丝点击