我花了很多时间试图找出为什么我在这段代码中有一个断言。
如果班级中没有析构函数,那就可以了。
你能解释一下,为什么我有一个包含析构函数的类的Assert whit。
我不想知道数组中元素的数量。我只想在课堂上有一个析构函数时理解Assert。
使用Visual C ++,“new”调用“malloc”函数。
=============================================== ======================================
更多细节:
使用:CTheClass * pArrayTheClass = new CTheClass [1];
在debug中,在_heap_alloc_dbg_impl()函数中, 你可以找到以下代码行: blockSize = sizeof(_CrtMemBlockHeader)+ nSize + nNoMansLandSize;
其中: sizeof(_CrtMemBlockHeader):32 nSize:4 nNoMansLandSize:4
之后,分配内存(withHeaderBlock), 并且函数将指针返回到数据部分。
在“new2.cpp”文件中的“operator new []”结尾处, 这个数据指针返回到程序分配。
但是 附: CTheClassWithDestructor * pArrayTheClassWithDestructor = new CTheClassWithDestructor [1]; 几乎是一样的......
但是nSize等于8; sizeof(int)+ 4 bytes
但是这次,即使在“operator new []的末尾,我们也有dataPart指针 在主程序中,我收到偏移量为4的指针。
如果我从指针中减去4,则在调用_msize()函数时没有断言。
解释Assert。 断言是因为这个偏移量为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;
}
答案 0 :(得分:1)
使用Visual C ++,
new
调用malloc
函数。
部分正确:代码中的new
表达式会调用operator new
来分配内存,而operator new
确实会调用malloc
。但是new
表达式产生的初始元素的指针不一定是从malloc
获得的指针。
如果动态分配需要销毁的对象数组(如CTheClassWith_string
类型),编译器需要跟踪数组中有多少元素,以便在{{{{{{ 1}}数组。
为了跟踪这一情况,编译器从delete
请求稍大的块,然后在块的开头存储一些簿记信息。然后malloc
表达式产生一个指向数组初始元素的指针,该指针偏离由new
由簿记信息分配的块的开头。