2015-10-13 137 views
1

我有一個類與構造函數和析構函數和一個其他方法。 當我創建這個類的新實例,然後它調用析構函數的地方,我不知道爲什麼。堆 - 構造函數和析構函數,內存分配

class Heap 
{ 
private: 
    int *heap; 
    int size; 
    int heap_size; 
public: 
    Heap(int new_size) 
    { 
     size = new_size; 
     heap_size = 0; 
     heap = (int*)malloc(new_size*sizeof(int)); //??? 
     //heap = new int[new_size]; //??? 
    } 
    ~Heap() 
    { 
     free(heap); 
    } 
    void add(int alfa) 
    { 
    // something 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    srand(time(NULL)); 
    int k = rand() % 100 + 1; 
    Heap *name = &Heap(k); 
    Heap *name2 = new Heap(k); //what's the diffrence? 
    while (k > 0) 
    { 
     name->add(rand()); // doesn't work, because destructor is called before 
     k--; 
    } 
    system("pause"); 
    return 0; 
} 
+4

'&堆(k)'您正在返回臨時地址。 –

+1

'main.cpp(31):warning C4238:使用非標準擴展:用作左值的類rvalue這應該是一個錯誤,但是微軟的編譯器默認破壞。永遠不要忽視那個警告。 –

+2

爲什麼你在班內使用'malloc'而不是'new []'? (但是,如果可能的話,你應該使用'std :: vector'或'std :: array'代替原始內存分配)。 – crashmstr

回答

3

在這個過程中運行該非標準一段代碼,其將最有可能產生未定義的行爲 無論如何,這條線

Heap *name = &Heap(k); 

產生臨時Heap對象在完整表達式的末尾被破壞。這導致析構函數被調用。

請注意,事實是,您的班級相當脆弱,因爲它不遵循the rule of three (five)。複製Heap對象將導致雙重刪除。


1出於很好的理由,標準C++不允許使用臨時地址。
2這種結構留給你一個懸掛指針。從技術上講,取消引用name會導致未定義的行爲。

+0

這是不合格的。 MS會不會改變完全破碎的默認值?它導致很多初學者寫出可怕的錯誤,甚至不應該編譯。 –

+0

@JonathanWakely對,我加了一個關於這個的筆記。 – juanchopanza

相關問題