当前位置: 首页 > 工具软件 > delete > 使用案例 >

VC中的delete和delete[]

公西凯捷
2023-12-01

 VC中的delete和delete[]

很多人在考虑delete和delete[]总是区分基本数据类型和用户自定义类型

 

但是我发现并非如此

int * p = new int[100];
我们调用delete p和delete[] p并没有任何问题,也检查不出内存泄漏

class A
{
public:
    int a;
    A( ) { }
};

A * p = new A[100];
我们调用delete p和delete[] p同样也没有任何问题,也检查不出内存泄漏

class A
{
public:
    int a;
    A( ) { }
    ~A( ) { }
};
A * p1 = new A[100];
A * p2 = new A;
我们调用delete p2和delete[] p1也没有任何问题,没有内存泄漏

但是我们调用delete p1和delete[] p2就立即出错

跟踪发现
void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
{
return ::operator new(nSize, nType, lpszFileName, nLine);
}
void __cdecl operator delete[](void* p)
{
::operator delete(p);
}
从上面的代码来看,new[]就是调用了new,delete[]也同样就是调用delete,为什么会出错呢,检查发现Debug下VC做了一些CRT断言,问题就出在_CrtIsValidHeapPointer这个函数上,这个函数是有源代码的,但不能跟踪无法发现错误,只能看到该函数返回出栈时出错。

那原因究竟在哪?

大家可以看到问题就在那个定义了的析购函数上。

还是继续跟踪有析购函数和无析购函数的情况
class A // 有析购函数
{
public:
    int a;
    A( ) { }
    ~A( ) { }
};
class B // 无析购函数
{
public:
    int b;
    B( ) { }
};

A * p1 = new A[1];
A * p2 = new A;

B * p3 = new B[1];
B * p4 = new B;

跟踪进去,你会发现
p1申请了8个字节
p2申请了4个字节
p3申请了4个字节
p4申请了4个字节

而p1使用delete直接删除就会出错,原因是内存长度不一致,那么多出来的这4个字节做什么用呢,我并没有继续跟下去,我想我差不多能猜出来了,这多出来的指针 。。。

 类似资料: