2013-11-28 41 views
1

当一个类的构造函数在堆上,例如分配内存堆栈展开动态创建的对象,其构造也作用在堆

class bla 
{ 
    private: 
     double *data; 
     int size; 

    public: 
     bla(int s) 
     { 
      size = s; 
      data = new double [size]; 
     } 
     ~bla() 
     { 
      delete[] data; 
     } 
} 

我有一个功能,例如,

void f(bool huge) 
{ 
    bla *ptr; 
    if (huge) 
     ptr = new bla(1e10); 
    else 
     ptr = new bla(1e2); 

    //... 

    delete ptr; 
} 

如果ptr = new bla(1e10)分配是SUCESSFUL(这意味着,datasize分配),但不构造会发生什么 - >他抛出异常,因为1E10是大?我有data = new double [size]没有内存泄漏,但我仍然存在堆上double *dataint size内存泄漏?或者它们是通过堆栈解除清理的?

我应该写它这种方式更好?:

void f(bool huge) 
{ 
    bla *ptr = 0; 
    try { ptr = new bla(1e10); } 
    catch (...) { delete ptr; throw; } 
} 

class bla 
{ 
    private: 
     double *data = 0; 
     // ... to not have an delete[] on a non-0 pointer 
} 

编辑

有点更精细的例子来说明templatetypedefs anwswer:

#include <iostream> 

using namespace std; 

class bla2 
{ 
private: 
    double *data; 

public: 
    bla2() 
    { 
     cout << "inside bla2 constructor, enter to continue"; 
     cin.get(); 
     data = new double [2*256*256*256]; 
    } 
    ~bla2() 
    { 
     cout << "inside bla2 destructor, enter to continue"; 
     cin.get(); 
     delete[] data; 
    } 
}; 

class bla 
{ 
private: 
    bla2 data1; 
    double data2[2*256*256*256]; 
    double *data3; 

public: 
    bla() 
    { 
     cout << "inside bla constructor, enter to continue"; 
     cin.get(); 
     data3 = new double [8*256*256*256]; // when only 1/4 as much -> then all success 
    } 
    ~bla() 
    { 
     cout << "inside bla destructor, enter to continue"; 
     cin.get(); 
     delete[] data3; 
    } 
}; 

void main() 
{ 
    bla *a; 
    cout << "program start, enter to continue"; 
    cin.get(); 
    try { a = new bla; } 
    catch (...) { cout << "inside catch, enter to continue"; cin.get(); exit(EXIT_FAILURE); } 
    cout << "success on a, enter to continue"; 
    cin.get(); 
    delete a; 
} 

白衣这个例子中,我可以在我的机器(Win7的4GB RAM)有关的ressource显示器,合得来看看怎么回事第一内侧bla2()然后bla()但后来因为没有~bla()因为失败分配data3首先调用~bla2(),然后结束(的)在catch(...)内存在基线上,就像程序启动时一样。

当我设置DATA3元素的数量只有1/4之多,那么所有succedes,与构造函数和析构函数的调用预期的顺序。

回答