Я трачу много времени, пытаясь выяснить, почему у меня есть утверждение в этом коде.
Если в классе нет деструктора, он работает хорошо.
Можете ли вы объяснить, почему у меня есть Assert с классом, содержащим деструктор.
Я не хочу знать количество элементов в массиве. Я просто хочу понять Assert, когда в классе есть деструктор.
С Visual C++ "новый" вызывает функцию "malloc".
================================================== ===================================
Более детально:
С помощью: CTheClass * pArrayTheclass= new CTheClass [1];
При отладке в функции _heap_alloc_dbg_impl() вы можете найти следующую строку кода: blockSize = sizeof (_CrtMemBlockHeader) + nSize + nNoMansLandSize;
где: sizeof (_CrtMemBlockHeader): 32 nSize: 4 nNoMansLandSize: 4
После этого выделяется память (withHeaderBlock), а функция возвращает указатель на часть данных.
И в конце "operator new []" в файле "new2.cpp" этот указатель данных возвращается к распределению программы.
Но с: CTheClassWithDestructor * pArrayTheClassWithDestructor = новый CTheClassWithDestructor [1]; почти то же самое...
но nSize равен 8; sizeof (int) + 4 байта
Но на этот раз, даже если в конце "operator new [] у нас есть указатель dataPart.
В основной программе я получаю этот указатель со смещением 4.
И если я вычитаю 4 из указателя, я не буду утверждать, когда вызываю функцию _msize().
Это объясняет утверждение. Утверждение является причиной этого смещения 4.
Вывод
Это смещение в 4 байта содержит количество элементов.
Если класс имеет деструктор, компилятор резервирует 4 байта для хранения количества элементов в массиве.
Если для вызова нет деструктора, у нас нет дополнительных 4 байтов в качестве смещения.
Благодарю Марка
#include <malloc.h>
class CTheClass
{
private:
int TheValue_;
};
class CTheClassWithDestructor
{
public:
~CTheClassWithDestructor()
{
int TheValue_ = 0;
}
private:
int TheValue_;
};
int _tmain(int argc, _TCHAR* argv[])
{
int size;
CTheClass* pArrayTheClass = new CTheClass[1];
size = _msize(pArrayTheClass);
delete [] pArrayTheClass;
CTheClassWithDestructor* pArrayTheClassWithDestructor
= new CTheClassWithDestructor[1];
size = _msize(pArrayTheClassWithDestructor); /// ASSERT On this line
delete [] pArrayTheClassWithDestructor;
return 0;
}
С Visual C++
new
вызовы функцииmalloc
.
Это отчасти верно: new
выражения в вашем коде требуют вызова operator new
для выделения памяти, а operator new
действительно вызывает malloc
. Но указатель на исходный элемент, который дает new
выражение, необязательно является указателем, полученным из malloc
.
Если вы динамически выделяете массив объектов, требующих уничтожения (например, ваш тип CTheClassWith_string
), компилятор должен отслеживать, сколько элементов находится в массиве, чтобы оно могло уничтожить их всех при delete
массива.
Чтобы отслеживать это, компилятор запрашивает немного больший блок из malloc
затем сохраняет некоторую бухгалтерскую информацию в начале блока. new
выражение затем дает указатель на исходный элемент массива, который смещается от начала блока, выделенного malloc
посредством информации о бухгалтерском учете.
CTheClassWith_int
уничтожение не требуется, поэтому компилятор не выделяет место для информации учета.