在一次软件 session 上的讨论之后,我着手确定使用普通 delete
删除动态分配的基元数组是否会导致内存泄漏。
我已经编写了这个小程序并使用在 Windows XP 上运行的 visual studio 2008 对其进行了编译:
#include "stdafx.h"
#include "Windows.h"
const unsigned long BLOCK_SIZE = 1024*100000;
int _tmain()
{
for (unsigned int i =0; i < 1024*1000; i++)
{
int* p = new int[1024*100000];
for (int j =0;j<BLOCK_SIZE;j++) p[j]= j % 2;
Sleep(1000);
delete p;
}
}
然后我使用任务管理器监视我的应用程序的内存消耗,令人惊讶的是内存被正确分配和释放,分配的内存没有像预期的那样稳定增加
我修改了我的测试程序以分配一个非基本类型数组:
#include "stdafx.h"
#include "Windows.h"
struct aStruct
{
aStruct() : i(1), j(0) {}
int i;
char j;
} NonePrimitive;
const unsigned long BLOCK_SIZE = 1024*100000;
int _tmain()
{
for (unsigned int i =0; i < 1024*100000; i++)
{
aStruct* p = new aStruct[1024*100000];
Sleep(1000);
delete p;
}
}
运行 10 分钟后内存没有明显增加
我编译了警告级别为 4 的项目,但没有收到任何警告。
Visual Studio 运行时是否有可能跟踪分配的对象类型,以便在该环境中 delete
和 delete[]
之间没有区别?
最佳答案
删除p,其中p是一个数组被称为未定义行为。
具体来说,当您分配一个原始数据类型 (int) 的数组时,编译器没有太多工作要做,所以它会将它变成一个简单的 malloc(),因此 delete p 可能会起作用。
删除 p 将失败,通常在以下情况下:
- p 是一个复杂的数据类型——删除 p;不知道调用单个析构函数。
- “用户”重载 operator new[] 和 delete[] 以使用与常规堆不同的堆。
- 调试运行时重载 operator new[] 和 delete[] 来为数组添加额外的跟踪信息。
- 编译器决定它需要与对象一起存储额外的 RTTI 信息,这会删除 p;不明白,但删除 []p;会。
关于c++ - delete p where p is a pointer to array always a memory leak?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2407724/