[英]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中閱讀有關此內容的更多信息。
此常見問題解答在p = new Fred [n]之后,編譯器如何知道在delete [] p期間要銷毀n個對象? 完全可以回答這個問題。
那是編譯器相關的細節。
調用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.