为什么此代码不导致内存泄漏?
int iterCount = 1000;
int sizeBig = 100000;
for (int i = 0; i < iterCount; i++)
{
std::auto_ptr<char> buffer(new char[sizeBig]);
}
WinXP sp2,编译:BCB.05.03
答案 0 :(得分:15)
因为你(非)幸运。 auto_ptr
来电delete
,而非delete []
。这是未定义的行为。
尝试做这样的事情,看看你是否幸运:
struct Foo
{
char *bar;
Foo(void) : bar(new char[100]) { }
~Foo(void) { delete [] bar; }
}
int iterCount = 1000;
int sizeBig = 100000;
for (int i = 0; i < iterCount; i++)
{
std::auto_ptr<Foo> buffer(new Foo[sizeBig]);
}
这里的想法是不会调用Foo
的析构函数。
原因是这样的:当你说delete[] p
时,delete[]
的实现假设转到数组中的每个元素,调用它的析构函数,然后释放p指向的内存。类似地,delete p
假设在p上调用析构函数,然后释放内存。
char
没有析构函数,所以它只是删除p指向的内存。在上面的代码中,不将破坏数组中的每个元素(因为它不会调用delete[]
),因此一些Foo将使其本地条形变量不被删除。
答案 1 :(得分:3)
auto_ptr只会在循环迭代期间存活,并会在迭代完成时释放连接到它的对象。
编译器可以看到,在这种情况下, new [] 可以以与 new 相同的方式分配空间 - 而无需在任何地方存储元素数量,因为不需要调用琐碎的char
析构函数 - 这就是为什么以后当auto_ptr的析构函数而不是 delete [] 调用 delete 时它会导致没有问题,因为内存块实际上已经存在已经以 new 的方式分配,并且该分配可以与 delete 配对。
这是一个不做的事情的例子。由编译器决定是否用 new 替换 new [] 。使用 delete 而不是 delete [] ,反之亦然是未定义的行为。
有关删除与删除[] 的讨论,请参阅Why would you write something like this? (intentionally not using delete [] on an array)。