【正确答案】
【答案解析】在C++中,申请动态内存与释放动态内存,用new/delete与malloc/free都可以,而且它们的存储方式相同,new与malloc动态申请的内存都位于堆中,无法被操作系统自动回收,需要对应的delete与free来释放空间,同时对于一般的数据类型,如int、char型,它们的效果一样。
malloc/free是C/C++语言的标准库函数,在C语言中需要头文件<stdlib.h>的支持,new/delete是C++的运算符。对于类的对象而言,malloc/free无法满足动态对象的要求,对象在创建的同时要自动执行构造函数,对象消亡之前要自动执行析构函数,而malloc/free不在编译器控制权限之内,无法执行构造函数和析构函数。
具体而言,new/delete与malloc/free的区别主要表现在以下几个方面:
1)new能够自动计算需要分配的内存空间,而malloc需要手工计算字节数。例如,int*p1=new int[2],int* p2=malloc(2*sizeof(int))。
2)new与delete直接带具体类型的指针,malloc与free返回void类型的指针。
3)new是类型安全的,而malloc不是,例如,int*p=new float[2],编译时就会报错;而int*p=malloc(2*sizeof(float)),编译时编译器就无法指出错误来。
4)new一般由两步构成,分别是new操作和构造。new操作对应于malloc,但new操作可以重载,可以自定义内存分配策略,不做内存分配,甚至分配到非内存设备上,而malloc不行。
5)new将调用构造函数,而malloc不能;delete将调用析构函数,而free不能。
6)malloc/free需要库文件stdlib.h支持,new/delete则不需要库文件支持。
程序示例如下:
#include<iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"A is here!"<<endl;
}
~A()
{
cout<<"A is dead!"<<endl;
}
private:
inti;
};
int main()
{
A* pA=new A;
delete pA;
return 0;
}
程序输出为
A is here!
A is dead!
需要注意的是,有资源的申请,就有资源的释放,否则就会出现资源泄露(也称内存泄露)的问题,所以new/delete,malloc/free必须配对使用。而且delete和free被调用后,内存不会立即收回,指针也不会指向空,delete或free仅仅是告诉操作系统,这一块内存被释放了,可以用做其他用途。但是,由于没有重新对这块内存进行写操作,所以内存中的变量数值并没有发生变化,出现野指针的情况。因此,释放完内存后,应该将指针指向置位空。
程序示例如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void TestFree()
{
char* str=(char*)malloc(100);
strcpy(str,"hello");
free(str);
if(str !=NULL)
{
strcpy(str,"world");
printf("%s/n",str);
}
}
int main()
{
TestFree();
return 0;
}
程序输出为
world
通过上例可知,free或delete调用后,内存其实并没有释放,也没有为空,而是还存储有内容,所以在将资源free或delete调用后,还需要将其置为NULL才行。
此时,便产生了一个问题,既然new/delete的功能完全覆盖了malloc/free,为什么在C++中没有取消掉malloc/free,而是仍然将其保留了?其实,由于C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存,所以仍然保留了malloc/free。