_msize Debug Assertion失败

时间:2014-02-28 05:39:50

标签: c++ visual-c++ memory-management

我花了很多时间试图找出为什么我在这段代码中有一个断言。

如果班级中没有析构函数,那就可以了。

你能解释一下,为什么我有一个包含析构函数的类的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个字节以保存数组中的元素数。

如果没有析构函数可以调用,我们没有额外的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;
}

1 个答案:

答案 0 :(得分:1)

  

使用Visual C ++,new调用malloc函数。

部分正确:代码中的new表达式会调用operator new来分配内存,而operator new确实会调用malloc。但是new表达式产生的初始元素的指针不一定是从malloc获得的指针。

如果动态分配需要销毁的对象数组(如CTheClassWith_string类型),编译器需要跟踪数组中有多少元素,以便在{{{{{{ 1}}数组。

为了跟踪这一情况,编译器从delete请求稍大的块,然后在块的开头存储一些簿记信息。然后malloc表达式产生一个指向数组初始元素的指针,该指针偏离由new由簿记信息分配的块的开头。