簡體   English   中英

Placement new是寫入比數組大小更多的字節

[英]Placement new is writing more bytes than array size

在下面的程序中,我希望用placement new覆蓋10個字節,然后為每個字節調用析構函數:

#include <memory>

struct MyChar {
    MyChar(char c = 'n') :c{c}{}
    ~MyChar(){ c = 'd'; }
    char c;
};

int main()
{
    {
        MyChar first[10]{0,1,2,3,4,5,6,7,8,9};
        new (first)MyChar[10]{10,11,12,13,14,15,16,17,18,19};
    }
    return 0;
}

但編譯器(*)警告將寫入18:

警告C6386:寫入'first'時緩沖區溢出:可寫大小為'10'字節,但可能寫入'18'字節。

首先,字節按預期寫入: 在此輸入圖像描述

但是編譯器並沒有虛張聲勢。 在放置新語句時,它寫入18個字節: 在此輸入圖像描述

這會導致錯誤:

運行時檢查失敗#2 - 變量'first'周圍的堆棧已損壞。

為什么不堅持10個字節? sizeof(MyChar)==1alignof(MyChar)==1


(*)Microsoft Visual Studio社區2017預覽(2)。 另外(但在編譯期間沒有警告)我在Microsoft Visual Studio Community 2017(版本15.2(26430.15)發行版)上獲得了相同的內存覆蓋和運行時錯誤。

放置新數組可能需要比N * sizeof(Object)更多的位置

(因為編譯器必須能夠使用delete[] ???)正確調用析構函數。

5.3.4 [expr.new]:

new(2,f) T[5]導致operator new[](sizeof(T)*5+y,2,f)的調用operator new[](sizeof(T)*5+y,2,f)

這里, xy是非負的未指定值,表示數組分配開銷; new-expression的結果將由operator new[]返回的值抵消。 這種開銷可以應用於所有數組新表達式,包括那些引用庫函數operator new[](std::size_t, void*)和其他放置分配函數的表達式。 開銷的數量可能因新的一次調用而異。 - 末端的例子]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM