2011-07-20 99 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版本,而不是指針。

雖然您的應用程序可能不允許。