簡體   English   中英

為什么new []分配額外的內存?

[英]Why is new[] allocating extra memory?

我正在閱讀“用C ++進行思考”,而我對新運算符感到困惑。 這是本書中的代碼:

//: C13:ArrayOperatorNew.cpp
// Operator new for arrays

#include <new> // Size_t definition
#include <fstream>

using namespace std;

ofstream trace("ArrayOperatorNew.out");

class Widget 
{
    enum { sz = 10 };
    int i[sz];

  public:

    Widget() { trace << "*"; }
    ~Widget() { trace << "~"; }

    void* operator new(size_t sz) 
    {
        trace << "Widget::new: "
              << sz << " bytes" << endl;
        return ::new char[sz];
    }

    void operator delete(void* p) 
    {
        trace << "Widget::delete" << endl;
        ::delete []p;
    }

    void* operator new[](size_t sz) 
    {
        trace << "Widget::new[]: "
              << sz << " bytes" << endl;
        return ::new char[sz];
    }

    void operator delete[](void* p) 
    {
        trace << "Widget::delete[]" << endl;
        ::delete []p;
    }
};

int main() 
{
    trace << "new Widget" << endl;
    Widget* w = new Widget;
    trace << "\ndelete Widget" << endl;
    delete w;
    trace << "\nnew Widget[25]" << endl;
    Widget* wa = new Widget[25];
    trace << "\ndelete []Widget" << endl;
    delete []wa;
} ///:~

這是“ ArrayOperatorNew.out”中跟蹤的內容

new Widget
Widget::new: 40 bytes
*
delete Widget
~Widget::delete
new Widget[25]
Widget::new[]: 1004 bytes
*************************
delete []Widget
~~~~~~~~~~~~~~~~~~~~~~~~~
Widget::delete[]

我對數字1004感到困惑。為什么不是1000? 這本書說:

這個額外的四個字節是系統保留有關的陣列的信息,特別是,在陣列中的對象的數量。

但是什么系統? 這是如何完成的? 編譯器在這里有幫助嗎?

使用new []時,運行時需要某種方式來記住分配的數組的大小,因此它知道使用delete []時要釋放多少內存。 在您的特定實現中,記住的方式是分配容納大小的額外四個字節(它不必以此方式工作)。

您可以在C ++ FAQ中閱讀有關此內容的更多信息。

那是編譯器相關的細節。

調用delete []時,僅傳遞一個參數-指向數組的指針。 為了正確運行,它必須知道要在正確數量的對象上執行析構函數的元素數量。 因此,它必須在某處獲取該信息。

典型的方法是new []為數組有效負載添加一個額外的size_t,用於存儲元素數量。 因此分配的空間量將是

sizeof( size_t ) + numberOfElements * sizeof ( ObjectType )

當使用new then分配數組時,在分配的塊的開頭使用一個附加字來保留分配的字節數。
由於C ++數組不保留有關其大小的信息,因此內存管理器必須在分配的內存大小上保留制表符,當使用delete []時,將讀取分配的字節數,然后由內存管理器收取該數量的內存。 這就是為什么對單個變量調用delete []會造成災難性的后果,而對數組調用delete會導致內存泄漏的原因。

內存管理必須保留一些有關內存塊大小的信息。 沒有這些信息,delete / delete []將無法正常工作(在刪除的情況下,如果編譯器知道要刪除的對象的大小,則可能不需要此信息)。

信息的保存方式以及新/刪除信息的實現細節在哪里。 它可能會根據您使用的編譯器或內存管理庫(例如SmartHeap)而改變。

有時會分配額外的內存來檢測編程錯誤(例如在分配的內存的邊界上寫)。

暫無
暫無

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

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