设为首页 加入收藏

TOP

细说C++中的new与delete(一)
2014-03-10 12:53:48 来源: 作者: 【 】 浏览:422
Tags:细说 new delete

  C++中内存的动态分配与管理永远是一个让C++开发者头痛的问题,本文通过对C++中内存的动态分配释放的基本原理的介绍,让读者朋友能对C++中的内存的动态分配与释放有较为深入的理解,从而更好驾驭C++程序。

  1. 函数(Function)

  (1) operator new function

  void * ::operator new(size_t);                  //Global

  void * class-name::operator new(size_t);    //Class

  上面是C++中operator new function的原型,一个是全局类型的,一个的类成员类型的。全局类型的operator new函数在下面两种情况下被调用:一种是在分配C++内建(built-in)类型的动态内存时,一种是在分配用户没有自己定义operator new成员函数的用户自定义类型的动态内存时。 如果用户在自己定义的类型中,定义了operator new函数,那么用户在用new申请该类型的动态内存时, 便会调用该类型的成员函数operator new, 而不是全局的operator new.

  另外,我们注意到,上面的原型中函数的返回值为void *类型, 第一个参数为size_t类型,这个是C++编译器要求的,如果要自己重载operator new函数,返回值必须为void* 类型,第一个参数必须为size_t类型,否则,编译器会返回如下错误信息:

  error: 'operator new' takes type 'size_t' ('unsigned int') as first parameter

  这里需要注意的一点是,我们可以利用operator new function可以重载的特点,可以通过参数传入一些额外的信息,来调试程序,检测内存泄露等。比如,我们可以像下面这样重载,传入调用处的行号,函数名,这样就可以跟踪内存的分配使用情况:

  void * operator new(size_t unSize, int nLine, const char * pFunc)

  {

  prinft("Line: %d, Func: %s, allocate %u byte(s)\n", nLine, pFunc, unSize);

  return malloc(unSize);

  }

  (2) operator delete function

  void operator delete( void * );

  void operator delete( void *, size_t );

  上面是operator delete function的原型。operator delete function也有全局的和类成员的两种。这里需要注意,一个类只能有一个operator delete function做为其成员函数,而且必须为上面两种中的其中一种,没有其它的形式。如果一个类实现了自己的operator delete function成员函数,那么在释放该类型的内存时,编译器便会调用成员operator delete function, 而不是全局的。

  上面的两种原型,第一种,在调用的时候,编译器会把要释放的内存的首地址传入,第二种,在调用的时候,编译器会把要释放的内存的首地址和大小都传入。因此,可以利用这一特性,如果我们在基类中实现第二种形式的operator delete function的成员函数,那么便可以用之来释放子类类型的内存(具体参考最后面的例子)。

  2. 运算符(Operator)

  (1) new operator

  [::] new [placement] new-type-name [new-initializer]

  [::] new [placement] ( type-name ) [new-initializer]

  注:上面的'[]'表示在其中的部分是optional(可选的)

  上面是new operator的原型。在C++中,动态内存的分配,通常都是调用new operator来完成的,利用new operator来分配动态内存,编译器要做下面两项工作:

  a. 调用operator new function分配内存(allocate the memory)

  b. 调用构造函数(call the constructor)来进行初始化

  下面来说一说new operator的原型中各部分到底是干什么的:

  placement: 如果你重载了operator new function, placement可以用来传递额外的参数

  type-name: 指定要分配的内存的类型,可以是内建(built-in)类型,也可以是用户自定义类型

  new-initializer: 指定对分配后内存的初始化的参数,也就的构造函数的参数 .这里需要注意一点,在分配一个对象的数组类型的内存时,不能够指定初始化参数;换言之,要想分配一个对象的数组类型的内存,该对象必须有缺省构造函数

  (2) delete opeartor

  [::] delete cast-expression

  [::] delete [ ] cast-expression

  上面是delete operator的原型,第一种用来释放普通的对象(包括内建类型)类型的内存,第二种用来释放对象的数组类型的内存。在C++中,用new operator分配的动态内存,必须调用delete operator来释放,通常用delete operator释放内存编译器要做下面两项工作:

  a. 调用对象析构函数来析构对象

  b. 调用operator delete function来释放内存(deallocate the memory)

  3. 关于new/delete使用过程中一些需要注意的点

  (1)如何区别operator new/delete function 与 new/delete operator

  通过上面的讲述,不难看出,我们分配/释放动态内存,调用的是new/delete operator, 而在调用new/delete的过程中,编译器会自动调用operator new/delete function来完成实际的内存分配/释放的工作

  (2) 用delete operator去释放一块不是由new operator释放的内存,结果是不可预料的,因此,切记,operator new与operator delete一定要配对使用,这是写好程序的基础

  (3) new operator调用失败会抛出std::bad_alloc异常,前提是你没有自己重载对应的operator new function;delete operator失败,常见的原因是多次delete同一块内存

  (4) 如果一块内存被delete后,再对它解引用(Dereference),结果也是不可预测的,很可能导致程序崩溃

  (5) delete一个空(NULL)指针是安全的,没有任何害处的

  (6) 类成员类型的operator new/delete函数必须为静态(static)函数,因此它们不能为虚函数(virtual function),也遵守public, protected, private的访问权限控制

     

首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++中的纯虚函数 下一篇C/C++取整函数ceil(),floor()

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Libevent C++ 高并发 (2025-12-26 00:49:30)
·C++ dll 设计接口时 (2025-12-26 00:49:28)
·透彻理解 C 语言指针 (2025-12-26 00:22:52)
·C语言指针详解 (经典 (2025-12-26 00:22:49)
·C 指针 | 菜鸟教程 (2025-12-26 00:22:46)