显式调用析构函数发生内存泄漏问题

下面的代码是矩阵类的一部分析构函数的语句,在稀疏矩阵的析构中显式调用了对象m_matrix的析构函数,开始看似没问题,但是程序执行后总是有内存泄露发生。
//SparseMatrix中全局变量
ccs_matrix* m_matrix;
//析构函数
SparseMatrix::~SparseMatrix()
{
if (this->m_matrix!=NULL){
this->m_matrix->~ccs_matrix();//在这里主动调用了对象的析构函数
}
this->m_matrix = NULL;
}
//结构ccs_matrix
struct ccs_matrix
{
int m,n;
int* colptr;
//构造函数
……
//析构函数
~ccs_matrix()
{
delete[] colptr;
}
}
后来感觉m_matrix是指针,每次创建它都用到了new,应该最后delete掉。于是将this->m_matrix->~ccs_matrix();语句改为delete this->m_matrix;这样内存泄漏问题就解决了。
在网上查了下,感觉下面说的很有道理,应该是问题症结。
delete有两步操作 
1.调用析构函数 
2.调用operator   delete释放内存
 

在c++里可以 
显示调用析构函数 

作用就是与 
placement   new相匹配 

一般比如分配一段内存作为内存池 

如下的 
#include   <iostream> 
#include   "tmp.h " 

using   namespace   std; 

class   A   { 
public: 
A(   int   i   )   :   _i(   i   )   {   cout   < <   "constructor/n ";   } 
void   print()   {   cout   < <   _i   < <   endl;   } 
~A()   {   cout   < <   "destructor/n ";   } 
private: 
int   _i; 
}; 

char   mem_pool[   20   ]; 
int main() 

A   *   pa   =   new   (   &   mem_pool[   0   ]   )   A(   25   ); 
pa-> print(); 
pa-> ~A(); 
return   0; 


这种情况就不能用delete 

有人说:  Deconstructor   is   the   same   as   other   member   functions,   it   won 't   erase   itself. 意思就是析构函数显式调用不会删除调用析构的对象自身,和上面一样,说明显式调用析构和delete的区别就是delete删除了对象自身

另外,显式调用析构函数有可能导致内存的两次释放,即调用时释放一次,自动析构时释放一次,导致程序错误。

顺便说明 构造函数和析构函数都可以显式调用,析构函数有时候必须显式调用。
 前两天去hp面试,有个题问构造函数和析构函数可不可以显示调用。 
  回来上网查了下,原来两个都是可以显示调用的。如下: 
  class A 
  { 
   public: 
   A()    { cout<<"a cnostructor"<<endl; } 
  ~A() { cout<<" a destructor"<<endl; } 
  }; 
  void main() 
  { 
   A a; 
   a.A::A();//显示调用构造函数,写成a.A()会报错。 
   a.~A();//显示调用析构函数,但是此时对象a并没有销毁。 
  } 
  此时的输出结果是: 
  a constructor 
  a constructor //显示调用构造函数的结果。 
  a destrucotr //显示调用析构函数的结果,此时对象并没有销毁。 
  a destructor //对象销毁时自动调用析构函数。 
  总结:显式调用构造函数和析构函数就想调用一般的函数一样,并不意味着创建或销毁对象。但是注意,如果构造函数中动态分配了空间,则显式调用构造函数会出现内存泄露;如果析构函数中释放动态分配的空间,则会出现多次释放同一内存,会出现严重错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值