2010-03-28 77 views
4

這是一個編譯器錯誤或運行時錯誤?下面的代碼可以編譯!如果我使用new或free來使用malloc,結果如何?

class Base{ 
void g(); 
void h(); 
}; 

int main() 
{ 
    Base* p = new Base(); 
    free(p); 
return 0; 
} 

但是它不能與虛擬功能,如果我聲明Base類這樣

class Base{ 
virtual void g(); 
void h(); 
}; 

下面的代碼可以編譯所有的時間編制,無論功能是虛擬的或不。

class Base{ 
void g(); 
void h(); 
}; 

int main() 
{ 
    Base* p = (Base*)malloc(sizeof(Base)); 
    delete p; 
return 0; 
} 
+9

結果是程序沒有定義的行爲。 – avakar 2010-03-28 22:29:11

+0

@avakar,爲什麼不把它作爲答案? – 2010-03-28 22:38:55

+1

@Poita - 顯然他想要*我*得分;-) – Steve314 2010-03-28 22:43:26

回答

11

未定義的結果,加上malloc()不調用構造函數,free()不調用析構函數。

+1

因爲行爲是未定義的,所以'free()'*可以*調用析構函數,如果你傳遞一個指向'new'的指針。我同意「它不」,因爲我懷疑它有什麼實現。 – 2010-03-28 23:18:54

+0

是的,但是您也面臨着由新分配的內存不能保證與免費兼容的問題。同上malloc和刪除。 – 2010-03-28 23:32:10

3

正如評論所說 - 結果是程序的行爲是未定義的。

如果你有「新」與「免費」,你的析構函數不會被調用。這通常會導致內存和資源泄漏。

如果你有「malloc」和「delete」,你不會得到構造函數調用,所以你的對象是未初始化的。這會導致各種錯誤,例如當析構函數被調用時。

如下面的註釋所示,即使不需要立即明確需要構造函數初始化,非POD類型(例如具有虛擬方法和使用虛擬繼承的類的類)也需要初始化。如果你malloc一個對象然後調用一個虛擬方法,最可能的結果就是你的程序會崩潰。到目前爲止,如果你的所有類型都是POD(普通舊數據),你可能會很幸運,但這很大程度上取決於你的編譯器 - 不能保證「malloc」和「new」使用相同的堆,所以你可能會在一些編譯器上發生堆損壞和崩潰。

總之 - 不要這樣做。

+0

你是對的,但在實踐中,我從來沒有遇到過一個不使用malloc/free來爲全局new/malloc分配內存的編譯器 - 雖然這當然不能依賴 – zebrabox 2010-03-28 22:38:33

+0

POD類型不能有虛擬函數,所以第二個不是POD類型。 – 2010-03-28 22:38:35

+0

@詹姆斯 - 我正在描述一般原則。正如你所說,虛函數是類型不是POD的明確證據,malloc的明顯問題是虛擬指針沒有初始化,所以對後期綁定方法的調用會崩潰。 – Steve314 2010-03-28 22:41:41

1

這是未定義的行爲。這意味着任何事情都可能發生 - 程序可能會成功,它可能會崩潰,它可能會在一段無關的無辜的代碼中失敗並崩潰,或者它甚至會擦除硬盤。

任何東西可能會發生,因爲你正在做的事情C++標準說不要做。