以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  [转帖]C基础下:Malloc()与free()的区别  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=125379)


--  作者:happem
--  发布时间:8/15/2012 2:45:00 PM

--  [转帖]C基础下:Malloc()与free()的区别
很多学员有疑问:有了malloc/free,为什么还要new/delete?

Malloc()与free()是C++/C语言的标准库函数,new/delete是C++的运算符,它们都可用于申请和释放动态内存。

对于非内部数据类型(如ADT/UDT)的对象而言,光用Malloc()与free()无法满足动态对象的要求,对象在创建的同时要自动调用构造函数,对象在销毁的时候要自动调用析构函数。由于Malloc()与free()是库函数而不是运算符,不在编译器控制权限之内,不能把调用构造函数和析构函数的任务强加给它们。因此C++语言需要一个能够完成动态内存分配和初始化工作的运算符new,以及一个能够完成清理与释放内存工作的运算符delete。

New/delete并非库函数,而是语言实现直接支持的运算符,就像sizeof()和typeid()及C++新增的4个类型转换运算符也不是库函数一样。

我们先看一看malloc()/free()和new/delete如何实现对象的动态内存管理,里仁教育嵌入式学院给大家列出代码如下:

Class obj

{

Public:

  Obj(){cout<<”construtor”<

~obj(){cout<<”destroy”<

Void Initialize(void){cout<<”initialize”<

Void Destroy(void){cout<<”destroy”<

};

Void usemallocfree(void)

{

Obj*a=(obj *)malloc(sizeof(obj)); //申请动态内存

a->Initialize();                //初始化

//…

a-> Destroy();                 //清除工作

free(a);                       //释放内存

}

Void UseNewDelete(void)

{

Obj*a=new obj;              //申请动态内存并调用构造函数来初始化

//…

Deleta a;                   //调用析构函数清除并且释放内存

}

类Obj的函数Initialize()模拟了构造函数的功能,函数Destroy()模拟了析构函数的功能。
在函数usemallocfree()中,由于malloc()/free()不能调用构造函数和析构函数,必须调用成员函数Initialize()和Destroy()来完成初始化和清除工作。函数UseNewDelete()则简单很多。
所以,我们不要企图用malloc()/free()来完成动态对象的内存管理,应该用new/delete。由于内部数据类型的”对象”没有构造与析构的过程,对它们而言malloc()/free()和new/delete是等价的。

下面里仁嵌入式培训学院讲师给大家扩展的讲解一下malloc()/free()和new/delete相关知识:

既然new/delete的功能完全覆盖了malloc()/free(),为什么C++不把malloc()/free()淘汰出局呢?这是因为有几下几点:

(1)C++程序经常要调用C函数,而且有些C++实现可能使用malloc()/free()来实现new/delete,而C程序只能用malloc()/free()来管理动态内存。

(2)使用new/delete更加安全,因为new可以自动计算它要构造的对象的字节数量,而malloc()则不能,new直接返回目标类型的指针,不需要显式地转换类型,而malloc()则返回void*,必须首先显式地转换成目标类型后才能使用。

(3)我们可以为自定义类重载new/delete,实现富有“个性”的内存分配和释放策略。而malloc()/free()不能被任何类重载,否则就改变了标准的定义。

(4)在某些情况下,malloc()/free()可以提供比new/delete更高的效率,因此某些STL实现版本的内存分配器会采用malloc()/free()来进行存储管理。

    如果用free()释放new创建的动态对象,那么该对象可能会因无法执行析构函数导致程序出错。C++标准并不保证new的底层实现会使用malloc(),更有甚者,在一些实现中malloc()和new使用不同的堆。同样,如果用delete释放malloc()申请的动态内存,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc()/free()也是一样。

函数malloc()原型如下:Void*malloc(size_t size);

用malloc()申请一块长度为length的整型数组的内存,程序如下:

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

我们应当把注意集中在两个要素上:“类型转换”和“sizeof”。

1、 malloc()函数返回值的类型是void*,所以在调用malloc()时要显式地进行类型转换,

将void*转换成所需要的指针类型。

2、 malloc()函数本身并不识别要申请的内存是什么类型,它只关心内存的总字节数。我们通常记不住int,float等数据类型变量的确切字节数。例如,int变量在16位系统下是2字节,在32位系统是4字节,而float变量在16位系统下是4字节,在32位下系统是4字节,最好用以下程序做个测试:

cout<<sizeof(char)<<endl;
cout<<sizeof(int)<<endl;
cout<<sizeof(unsigned int)<<endl;
cout<<sizeof(long)<<endl;
cout<<sizeof(unsigned long)<<endl;
cout<<sizeof(float)<<endl;
cout<<sizeof(double)<<endl;
cout<<sizeof(void*)<<endl;
在malloc()函数的“()”中使用sizeof运算符是良好的风格,但是当心有是昏了头,写出

P=malloc(sizeof(p))这样的错误程序来!


函数free的原则型如下:


Void free(void * memblock);

为什么free()函数不像malloc()函数那样复杂呢?这是因为指针p的类型及它所指的内存容量事先都是知道的,语句free(p)能正确地释放内存。

如果p是NULL指针,那么函数free()对p无论操作多少次都不会出问题。如果p不是NULL指针,那么函数free()对p连续操作两次就会导致程序运行时出现错误。
来自:嵌入式培训 “http://www.lirenedu.org/index.php?ack=xinwen&id=1006 ”


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
31.250ms