2011-07-20 98 views
1

所以在C++,如果我创建了一个对象期运用new,我应该使用delete
例如困惑C++内存释放

Segment::Segment(float length) 
{ 
    segmentLength = length; 

    angle = 0.0f; 
    x = Rand::randFloat(1.0f, 1.5f); 
    y = Rand::randFloat(1.0f, 1.5f); 

    vx = Rand::randFloat(0.0f, 1.0f); 
    vy = Rand::randFloat(0.0f, 1.0f); 
    prevX = Rand::randFloat(0.0f, 1.0f); 
    prevX = Rand::randFloat(0.0f, 1.0f); 
}; 

总是释放它而可以说我像这样使用另一个类,例如,

this._segmentObject = Segment(2.0f); 
this._segmentPointer = new Segment(2.0f); 

那堂课,我知道我应该在this._segmentPointer调用delete的析构函数,但我怎么确保内存被释放了另外一个?

回答

4

未分配的物品new,new[]malloc家族应该在物体超出范围时被销毁和“释放”。

通常这只是意味着代码已经到达它声明的块的末尾,或者它所在的对象被破坏了(以这种或那种方式)。

要看到这个动作,你可以做这样的事情:

struct C { 
    C() { std::cout << "C()" << std::endl; } 
    ~C() { std::cout << "~C()" << std::endl; } 
}; 

struct B { 
    B() { std::cout << "B()" << std::endl; } 
    ~B() { std::cout << "~B()" << std::endl; } 
private: 
    C c_; 
}; 

struct A { 
    A() { std::cout << "A()" << std::endl; } 
    ~A() { std::cout << "~A()" << std::endl; } 
}; 

int main() { 
    B *b = new B; // prints "B()", also constructs the member c_ printing "C()" 
    { // starts a new block 
     A a; // prints "A()"; 
    } // end of block and a's scope, prints "~A()" 

    delete b; // prints "~B()", also destructs member c_, printing "~C()" 
} 

注意:如果我们没有做delete b,在 “〜B()” 和 “〜C()” 永远不会打印。同样地,如果c_被一个指针与new分配,这将需要是delete“为了打印D‘〜C()’

0

_segmentObject自动分配在堆栈上。 当变量超出范围时,将自动调用对象析构函数。

+0

“_segmentObject自动分配在堆栈上” - 这是错误的。它可能在堆上分配(例如在另一个对象内部)。然而,这是无关紧要的。 –

+0

它没有在堆栈上分配 – Novikov

5

但是,如何确保内存被释放为另一个?

它是自动的。这就是为什么这种类型的存储称为自动。自动存储在存储的生命周期结束时释放,并调用对象的析构函数。

当程序控制离开分配对象的范围时,对象生命周期结束。

3

为this._segmentObject存储器是包含对象的存储器的一部分,并且将在包含对象被销毁时释放。

this._segmentObject是从堆栈上创建的临时对象中分配的,并在超出范围时被删除。

1

不仅如此,您应该只分配新的和释放与构造函数或析构函数删除,否则您的程序可能会泄漏,如果引发异常。

1

在销毁主类时调用所有类类型成员对象的析构函数。因此,在堆栈中分配的对象将在其超出范围时调用析构函数。那时,你的this对象的任何类类型的成员对象除了你的this对象的析构函数之外,还将拥有自己的析构函数,它将在成员指针上调用delete

例如,采取下面的代码示例:

#include <iostream> 

using namespace std; 

class A 
{ 
     public: 
       A() {} 
       ~A() { cout << "Destructor for class A called" << endl; } 
}; 

class B 
{ 
     private: 
       A a; 

     public: 
       B() {} 
       ~B() { cout << "Destructor for class B called" << endl; } 
}; 

int main() 
{ 
     B b; 
     return 0; 
} 

运行时,输出端变为:

Destructor for class B called 
Destructor for class A called 

所以你可以看到,当b,这是在栈上分配,在main结束时超出范围,类B的destrutor被调用,这反过来,在执行析构函数的主体之后,调用任何它的类类型成员数据对象的析构函数whi ch在这种情况下意味着类A的析构函数。因此,在你的情况下,指针将在你的this类的析构函数中调用delete,然后在析构函数this已经完成其析构函数体的执行后调用析构函数_segmentObject。然后,一旦调用了非静态数据成员对象的所有析构函数,则返回this的析构函数。

0

正如其他人所说,您不需要明确地做任何事情来收回this._segmentObject所使用的内存。一旦超出范围,内存将被回收。

目前尚不清楚为什么您会以两种方式使用Segment。您应该尝试确保使用​​成语,因为它消除了检查new/delete对的大部分需求。也就是说,只需使用this._segmentObject版本,而不是指针。

虽然您的应用程序可能不允许。