new和delete运delete和delete[]&nb…

来源:互联网 发布:比较好的经济类数据库 编辑:程序博客网 时间:2024/06/05 16:01

new和delete运算符用于动态分配和撤销内存的运算符

new用法:

         1.    开辟单变量地址空间

              1)new int;  //开辟一个存放数组的存储空间,返回一个指向该存储空间的地址.int *a= new int 即为将一个int类型的地址赋值给整型指针a. 

              2)int *a = new int(5) 作用同上,但是同时将整数赋值为5

         2.    开辟数组空间

              一维: int *a = new int[100];开辟一个大小为100的整型数组空间

              二维: int **a = new int[5][6]

              三维及其以上:依此类推.

        一般用法: new 类型 [初值]

delete用法:

         1. int *a = new int;

              delete a;   //释放单个int的空间

         2.int *a = new int[5];

              delete [] a; //释放int数组空间

 

         要访问new所开辟的结构体空间,无法直接通过变量名进行,只能通过赋值的指针进行访问.

         用new和delete可以动态开辟,撤销地址空间.在编程序时,若用完一个变量(一般是暂时存储的数组),下次需要再用,但却又想省去重新初始化的功夫,可以在每次开始使用时开辟一个空间,在用完后撤销它.
new\delete玩的是对象,而malloc\free仅仅是内存空间而已

2 对于除去对象意外的其他情况,比如int和float等
int* Array=new int[10];和int*Array=malloc(sizeof(int)*10);只存在使用技巧的差别,没有本质的差别。

3 最后也提醒你new\delete和malloc\free只能成对使用,不能混了。

 


malloc/free和new/delete的区别


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

对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。

我们先看一看malloc/free和new/delete如何实现对象的动态内存管理,见下面示例。


class Obj
{
public :
    Obj(void){cout << “Initialization” << endl; }
    ~Obj(void){cout << “Destroy” << endl; }
    voidInitialize(void){ cout << “Initialization” << endl;}
    voidDestroy(void){ cout << “Destroy” << endl; }
};

void UseMallocFree(void)
{
   Obj  *a = (obj*)malloc(sizeof(obj));   //申请动态内存
   a->Initialize();                       // 初始化
    //…
   a->Destroy();   // 清除工作
   free(a);       // 释放内存
}

void UseNewDelete(void)
{
   Obj  *a = new Obj;  //申请动态内存并且初始化
    //…
    deletea;          // 清除并且释放内存
}


类Obj的函数Initialize模拟了构造函数的功能,函数Destroy模拟了析构函数的功能。函数UseMallocFree中,由于malloc/free不能执行构造函数与析构函数,必须调用成员函数Initialize和Destroy来完成初始化与清除工作。函数UseNewDelete则简单得多。

所以我们不要企图用malloc/free来完成动态对象的内存管理,应该用new/delete。由于内部数据类型的“对象”没有构造与析构的过程,对它们而言malloc/free和new/delete是等价的。

既然new/delete的功能完全覆盖了malloc/free,为什么C++不把malloc/free淘汰出局呢?这是因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。
如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc/free也一样。 


delete和delete[] 的区别


我的理解:对于一个数组,delete和delete[]都可以释放内存空间,但是只有delete[]才会调用每一个数组元素的析构函数,而delete只能调用第一个数组元素的析构函数。对于基本数据类型,没有析构函数,所以使用delete和delete[]没有区别。

网上搜到的一个解答,原始出处是http://bbs.chinaunix.net/
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用delete[]。

楼主的这个问题提得很好。很多人注意到了这个问题,但是却不清楚为什么要这样做,不这样做行不行。

关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2)为自定义类型分配和回收空间。

对于 (1),上面提供的程序已经证明了 delete[] 和 delete 是等同的。但是对于(2),情况就发生了变化。请看下面的程序。


#include
using namespace std;

class T {
public:
  T() { cout << "constructor" << endl;}
  ~T() { cout << "destructor" << endl;}
};

int main()
{
  const int NUM = 3;

  T* p1 = new T[NUM];
  cout << hex << p1 <<endl;
  //  delete[] p1;
  delete p1;

  T* p2 = new T[NUM];
  cout << p2 << endl;
  delete[] p2;
}


大家可以自己运行这个程序,看一看 delete p1 和 delete[] p1 的不同结果,我就不在这里贴运行结果了。

从运行结果中我们可以看出,delete p1 在回收空间的过程中,只有 p1[0] 这个对象调用了析构函数,其它对象如p1[1]、p1 [2] 等都没有调用自身的析构函数,这就是问题的症结所在。如果用delete[],则在回收空间之前所有对象都会首先调用自己的析构函数。

基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[]都是应该可以的;但是对于类对象数组,只能用 delete[]。对于 new 的单个对象,只能用 delete 不能用 delete[]回收空间。

所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。

0 0
原创粉丝点击