2013-07-14 58 views
7

我知道,調用delete on一個使用placement new創建的變量然後訪問該內存塊具有未定義的行爲。關於展示位置刪除新

int* x = new int[2]; 
char* ch = new(x) char(); 
*ch = 't'; 
delete ch; 

但如果內存塊,而不是堆,被分配在堆棧中,然後我們呼籲刪除該變量,然後訪問內存,我得到一個異常的塊類型無效

int x[2]; 
char* ch = new(x) char(); 
*ch = 't'; 
delete ch; 

這樣的問題清單是:

  • 是由於調用刪除堆棧上的異常?
  • 在堆棧上的內存塊上使用放置新功能可以嗎?
  • 如果是,那麼我應該如何刪除字符指針。
  • 是否可以使用放置新功能在一塊 內存上分配多個變量?
+1

http://www.parashift.com/c++-faq/placement-new.html – Drax

回答

16

由於調用堆棧上的刪除而導致異常嗎?

是的。雖然澄清一點,但這不是C++的例外。這是運行時檢測到的錯誤。如果運行時不是那麼聰明,你也可能遇到未定義的行爲。

在堆棧上的內存塊上使用放置新功能可以嗎?

是的。你也可以看看alloca()Variable-length arrays(VLA) - 這是另外兩種在堆棧上分配內存的機制。請注意,VLA是C99的一部分,而不是C++ 11(及更早版本)的標準,但作爲擴展(它可能出現在C++ 14中)被大多數生產級編譯器支持。

如果是,那麼我應該如何刪除字符指針。

您不應該。當您使用新的展示位置時,您不需要撥打delete,只需調用析構函數即可。對於T類型的任何給定對象o,您需要致電o->~T();而不是delete o;。但是,如果您必須處理在這樣的對象上調用deletedelete []的代碼,則可能需要重載運算符deletedelete[],並使這些運算符不會執行任何操作(析構函數已在該點運行)。

是否可以使用放置新分配一個內存塊上的多個變量?

是的。但是,您需要格外小心,以確保您符合alignment requirements

+0

一個很好的答案。但只是澄清一點。當在堆棧上使用新放置時,將從開始處開始分配內存,然後向前移動或在給定塊中隨機分配內存。似乎第一個選項是正確的。糾正我,如果我錯了 – Saksham

+0

@Saksham:安置新沒有分配任何內存。它使用指定的參數作爲參數。至於如何在堆棧上分配內存 - 取決於架構,它可能會向內或向外擴展。但是,堆棧中的任何單個對象的基地址都會較低,因此如果要使用'placement new []'放置多個對象,請一次爲它們分配內存。 – 2013-07-14 14:30:35

+0

對於「已分配內存」的語言不正確,我的行爲不好。它應該是「內存使用」 – Saksham