2013-10-04 21 views
0

我使用「放置新」來分配我的對象。我使用三種記憶清除方式。他們都是安全的嗎?我可以得到內存泄漏嗎?我使用三種內存清除方式。他們都是安全的嗎?我可以得到內存泄漏嗎?

#include <iostream> 
#include <exception> 
#include <vector> 
using namespace ::std; 

class A{ 
private: 
    double x; 
public: 
    A() : x(0) { cout << "A class; ptr: " << this << " created." << endl; } 
    ~A() { cout << "A class; ptr: " << this << " destroyed." << endl; } 
}; 

int main(int argc, char* argv[]) 
try{ 
    // 1. Creating of object in the necessary memory address 

    static_assert(sizeof(char) == 1, "Unexpected size of char."); 
    int x = -1; // Variants of memory clearing 
    while (x < 0 || x > 2) { 
     cout << "Variant (0,1,2): "; 
     cin >> x; 
    } 
    char* p = new char[sizeof(A)]; // some memory area... 

    A* a = new(p)A(); // Place my object in the 'p' address. 

    // Here is my basic work to do... 

    // Now I must to free my memory: 
    if(!x){ // First variant 
     delete a;   
    } 
    else if (x == 1){ // Second variant 
     delete reinterpret_cast<A*>(p); 
    } 
    else if (x == 2){ // Third variant 
     a->~A();   
     delete[] p; 
    } 
    else{ 
     throw runtime_error("Invalid variant!"); 
    } 
    a = nullptr; 
    p = nullptr; 

    cout << endl; 
} 
catch(exception& e){ 
    cerr << e.what() << endl; 
    return 1; 
} 
catch(...){ 
    cerr << "Unknown exception." << endl; 
    return 2; 
} 

謝謝。

+1

當你的問題簡單地重複標題時,它通常意味着你沒有足夠的描述:p可能解釋你的三個變體(我知道你的代碼很短,但仍然有幫助) – keyser

+6

你應該**永遠不會* *明確地調用析構函數!當實例超出範圍或調用delete時,它們將自動調用。 –

+2

''char'需要1個字節長的標準,斷言是多餘的。 – 2013-10-04 13:19:24

回答

3

delete[]和明確的析構函數調用的變體是正確的,因爲它是你如何分配的鏡面反射/構建它:

char* p = new char[sizeof(A)]; 
A* a = new(p)A(); 
... 
a->~A();   
delete[] p; 

但是,如果你沒有很好的理由使用放置新的,考慮簡單而直接:

A* a = new A(); 
... 
delete a; 

雖然delete應該呼籲每個newdelete[]每一個new[],因爲你分配的0陣列s,第二個選項似乎不是很合理,但仍然合法(只要您確定內存塊的大小真的等於sizeof(A),並且存在此類型的有效對象A即可陣列):

char* p = new char[sizeof(A)]; 
delete reinterpret_cast<A*>(p); 

另外請注意,下面的行是完全無用的:

static_assert(sizeof(char) == 1, "Unexpected size of char."); 

,因爲它是由標準保證sizeof(char)總是返回1.

+0

>避免這樣做,只是做... 我知道。我的問題是關於其他。 –

+0

>重要的是要知道,每個新的[]都應該爲每個新的[]刪除[],並刪除[]。如果你使用新的[],然後嘗試釋放這個內存使用刪除... 我知道。我的指針指向相同的內存地址。禁止爲同一個指針調用delete \ delete []兩次。 –

+0

@Bush:第二個選項依賴於兩個事實:1.p指向的內存塊的大小等於sizeof(A),2.一個有效的對象存儲在這個內存中,這樣將調用適當的析構函數。 – LihO

1

第三個變體是刪除對象並清除已分配內存的正確方法。