亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

可以以可移植的方式使用陣列的新放置嗎?

可以以可移植的方式使用陣列的新放置嗎?

C++
千巷貓影 2019-10-30 10:10:10
將其用于數組時,是否可以實際利用可移植代碼中的新放置?從new []返回的指針似乎并不總是與您傳遞的地址相同(5.3.4,標準中的注12似乎確認這是正確的),但我看不出您如何在這種情況下,可以為數組分配一個緩沖區。以下示例顯示了該問題。與Visual Studio一起編譯,此示例導致內存損壞:#include <new>#include <stdio.h>class A{    public:    A() : data(0) {}    virtual ~A() {}    int data;};int main(){    const int NUMELEMENTS=20;    char *pBuffer = new char[NUMELEMENTS*sizeof(A)];    A *pA = new(pBuffer) A[NUMELEMENTS];    // With VC++, pA will be four bytes higher than pBuffer    printf("Buffer address: %x, Array address: %x\n", pBuffer, pA);    // Debug runtime will assert here due to heap corruption    delete[] pBuffer;    return 0;}看著內存,編譯器似乎正在使用緩沖區的前四個字節來存儲其中的項目數計數。這意味著,由于緩沖區僅sizeof(A)*NUMELEMENTS大,因此數組中的最后一個元素將寫入未分配的堆中。因此,問題是您能找出為了安全地使用位置new []而實現需要多少額外開銷?理想情況下,我需要一種可在不同編譯器之間移植的技術。請注意,至少在VC的情況下,不同類的開銷似乎有所不同。例如,如果我在示例中刪除了虛擬析構函數,則new []返回的地址與我傳入的地址相同。
查看完整描述

3 回答

?
FFIVE

TA貢獻1797條經驗 獲得超6個贊

就我個人而言,我可以選擇不在數組上使用新的展示位置,而是在數組中的每個項目上單獨使用新的展示位置。例如:


int main(int argc, char* argv[])

{

  const int NUMELEMENTS=20;


  char *pBuffer = new char[NUMELEMENTS*sizeof(A)];

  A *pA = (A*)pBuffer;


  for(int i = 0; i < NUMELEMENTS; ++i)

  {

    pA[i] = new (pA + i) A();

  }


  printf("Buffer address: %x, Array address: %x\n", pBuffer, pA);


  // dont forget to destroy!

  for(int i = 0; i < NUMELEMENTS; ++i)

  {

    pA[i].~A();

  }    


  delete[] pBuffer;


  return 0;

}

無論使用哪種方法,請確保在刪除pBuffer之前手動銷毀數組中的每個項,否則可能會導致泄漏;)


注意:我還沒有編譯它,但是我認為它應該可以工作(我在沒有安裝C ++編譯器的計算機上)。它仍然表明要點:)希望它能以某種方式有所幫助!


編輯:


之所以需要跟蹤元素的數量,是因為當您在數組上調用delete并確保在每個對象上都調用了析構函數時,它可以遍歷它們。如果不知道有多少個,它將無法執行此操作。


查看完整回答
反對 回復 2019-10-30
?
米琪卡哇伊

TA貢獻1998條經驗 獲得超6個贊

5.3.4的第12節討論了數組分配的開銷,除非我誤讀了它,否則似乎暗示我編譯器也可以將其添加到new位置上:


此開銷可能會應用于所有數組new-expression,包括引用庫函數operator new [](std :: size_t,void *)和其他布局分配函數的那些表達式。開銷量可能從一個新調用到另一個調用而有所不同。


就是說,我認為VC是唯一給我帶來麻煩的編譯器,其中包括GCC,Codewarrior和ProDG。不過,我必須再次檢查以確保。


查看完整回答
反對 回復 2019-10-30
?
慕后森

TA貢獻1802條經驗 獲得超5個贊

Placement new本身是可移植的,但是您對它對指定內存塊所做的假設不是可移植的。就像之前所說的,如果您是一個編譯器并且被分配了一塊內存,那么如果您擁有的只是一個指針,您如何知道如何分配一個數組并正確地破壞每個元素?(請參閱運算符delete []的界面。)

編輯:

實際上存在一個放置刪除,只有在構造函數使用放置位置new []分配數組時構造函數引發異常時才調用它。

new []是否實際上需要以某種方式跟蹤元素的數量,這取決于標準,由標準決定。不幸的是,在這種情況下。


查看完整回答
反對 回復 2019-10-30
  • 3 回答
  • 0 關注
  • 381 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號