被无视的伊谢尔伦

雕栏玉砌应犹在,只是朱颜改

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  9 随笔 :: 0 文章 :: 6 评论 :: 0 Trackbacks

 

const   int  BUF  =   512  ;

class  JustTesting
{
    
private :
        JustTesting(
const   string   &  s  =   " Just Testing " , int  n  =   0 )
        
{}  
        
~ JustTesting() {}
    
public :
    
}
;

int  main()
{
    
char   *  buffer  =   new   char  [BUF];

    JustTesting 
* pc1, * pc2, * pc3, * pc4;

    pc1 
=   new  (buffer) JustTesting;
    pc2 
=   new  JustTesting(  "  Heap1  "  ,  20  );

    pc3 
=   new  (buffer  +   sizeof  (JustTesting)) JustTesting( " Bad Idea " , 6 );   //  此处用一个JustTesging对象大小的偏移量避免pc3与pc1占用同一块内存,因为如果类动态的为其成员分配内存,占用同一内存将会产生问题。 
    pc4  =   new  JustTesting( " Heap2 " , 10

    

    delete pc2;
    delete pc4;
    delete [] buffer;
    
return   0 ;
}


以上代码片断中,pc1和pc3为布局new操作符来分配内存,而pc2和pc4为常规new操作符来分配内存 。
对于常规new操作符分配的内存,可以直接使用:delete pc2; 这样的语句操作来释放内存。

而对于布局new操作符分配的内存就不能这样做:delete pc1;

因为pc1和pc3并没有直接收到new操作符返回的地址,而是由布局操作符指向了buffer的地址,new/delete系统知道已分配的512字节块buffer,但对布局new操作符对该内存块做了何种处理一无所知。
另一方面,buffer的地址是用new []初始化的,因此必须使用delete[]而不是delete
注意:即使buffer是使用new而不是new[]初始化的,delete pc1 也将释放buffer,而不是pc1。

以上的代码确实释放了buffer:delete [] buffer;
但是由此产生了新的问题,它没有为布局new操作符在该内存块中创建的对象调用析构函数,我们只需要在析构函数中放入一段显示语句就可以清楚的看到,程序并没有销毁“JustTesting”和“Bad Idea”,也就是pc1和pc3指向的对象。
那么这里就需要我们显式的为布局new操作符创建的对象调用析构函数。正常情况下将自动调用析构函数,这是需要显示调用析构函数的少数几种情况之一。
显式调用析构函数时,必须指定要销毁的对象。由于有指向对象的指针,因此可以这样写:

pc3->~JustTesting();
pc1->~JustTesting();

把这段代码放到delete [] buffer;之前,这段程序才算完整无错。

参考书籍:C++PrimerPlus author:Stephen Prata

posted on 2006-09-28 14:42 爱上青菜的包子 阅读(2287) 评论(3)  编辑 收藏 引用 所属分类: C++

评论

# re: C++学习笔记:关于C++类与动态内存分配中布局new操作符 2006-09-29 12:39 天性如此
考,我都看不懂呢,我只知道皮毛丫  回复  更多评论
  

# re: C++学习笔记:关于C++类与动态内存分配中布局new操作符 2008-08-13 11:52 AlexEric
有深度。  回复  更多评论
  

# re: C++学习笔记:关于C++类与动态内存分配中布局new操作符 2011-08-08 21:17 normalbe
不错,很精辟,跟c++ primer plus上的讲解有一拼了  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理