2012-03-15 53 views
0

基於此問題:Variable size type allocation安置新獲得動態大小

請問以下工作?

{ 
    // size calculated. 
    std::auto_ptr<Base> p(new((void*)(new char[size])) Packet()); 

    // Do Stuff 
} 

其中分組是POD結構,其中最後構件是一個數組。這個想法是允許動態大小的數組(就像我們所有這些年前使用C++做的)

struct Packet 
{ 
    // STUFF 
    int data[1]; 
} 
+2

我有一種感覺[這個問題](http://stackoverflow.com/q/5520591/500104)是非常相關的。 – Xeo 2012-03-15 05:21:53

+1

對不起,如果我誤解這裏的東西。但是,你基本上問是否可以使用'delete'(而不是'delete []')來釋放使用'new []'分配的內存? – jogojapan 2012-03-15 06:44:52

回答

1

不,這不工作:與任何形式的比std::nothrow需要其他new採取了額外的參數構造的對象顯式地銷燬,內存被照顧的分別:

void* memory = operator new(size); 
T* ptr = new(memory) T(args); 
... 
ptr->~T(); 
operator delete(memory); 

還要注意分配原始內存的方式是不new char[size]:此構造中,需要爲d內存char對象estroyed。我意識到,既沒有構造也沒有破壞實際上對內置類型做任何事情,但我很漂亮,實現可以做某些事情,並且據我所知,沒有權限跳過這些析構函數。

最後,請注意,您還需要構建int對象,並允許實現將某些東西放在結構的明顯結尾之後。

0

我很抱歉,如果我錯過了一個重要的點,這是在某種程度上隱含在問題中,我沒有看到它。但是,對於這中線:

std::auto_ptr<Base> p(new((void*)(new char[size])) Packet()); 

這是我覺得能一下說:

  1. 末的構造函數調用應該是Packet,不Packet(),但在實踐中,編譯器可能會接受它,它可能沒有任何區別

  2. 內部分配new char[size]使用數組分配器new []。關於表達new [array_n]CPP reference狀態:

注意,多於size_of(型)* array_n可能由於由編譯器(如陣列的大小編碼的附加信息被分配,因爲該信息以便正確地破壞陣列中的物體)。現在

,外部分配器通話,new ((void*)(...)),是安置新,被描述here如下的實例:

void* operator new (std::size_t, void* ptr);什麼都不做,返回PTR。

換句話說,它可能發生該呼叫到new []使編譯器分配比由陣列和在額外的空間編碼大小有關的信息嚴格要求更多的存儲器。但是,由於展示位置新功能「無」,因此不會以任何方式處理或刪除額外信息。

但是,因爲使用的std::auto_ptr意味着該解除分配將利用delete(和delete [])來進行,該額外的信息將無法正確釋放,因此內存泄漏或更差可能導致。

編輯:爲了避免僅依賴於CPP的參考,C++ Standard N3337的相關部分如下:

  • §只有delete應當用於釋放空間,通過new分配18.6.1.2狀態,並且相應delete []分配的空間由new []
  • §18.6.1.3明確指出newnew []的佈局表單不執行任何操作。這意味着它們都不能用於將單個對象空間「轉換」爲數組空間。

現在也許真正的問題是如果只delete []使用後解除分配的空間放置新的問題所提出的申請是否有效。也許答案是不確定的(這應該被解釋爲等同於「否」)。

+0

實際上'新的數據包'和'新的數據包()'都是有效的(雖然有稍微不同的含義(第二個將零初始化結構,第一個將默認初始化結構))所以它沒有錯或壞。 – 2012-03-15 16:28:03

+0

請不要使用cpprefeence作爲源。它包含很多錯誤。免費使用它作爲一個起點,但當你開始引用某些權威來源時,它應該是標準。此外額外的空間添加不會影響返回的內存,因爲它不是返回的內存的一部分(標準有一定的保證,沒有違反額外的空間不是這個的一部分,也不影響這些保證)。獲取此處的標準副本:http://stackoverflow.com/a/4653479/14065 – 2012-03-15 16:33:56

+1

是auto_ptr <>調用錯誤的刪除。 – 2012-03-15 16:34:31