为什么这段代码不会导致内存泄漏?
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
为什么这段代码不会导致内存泄漏?
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
因为你(不)幸运。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
's 没有析构函数,所以它只会删除 p 指向的内存。在我上面的代码中,它不会破坏数组中的每个元素(因为它没有调用delete[]
),所以一些 Foo 将保留其本地 bar 变量未删除。
auto_ptr 将仅在循环迭代期间存在,并在迭代完成时释放与其连接的对象。
编译器可以看到,在这种情况下,new[]可以以与new相同的方式分配空间——无需在任何地方存储元素的数量,因为不需要调用琐碎char
的析构函数——这就是为什么稍后当auto_ptr 的析构函数调用delete时的delete[]它不会导致任何问题,因为内存块实际上已以new的方式分配,并且该分配可以与delete配对。
This is an example of a thing not to do. It's up to the compiler to decide whether to replace new[] with new. Using delete instead of delete[] and vice versa is undefined behaviour.
See Why would you write something like this? (intentionally not using delete [] on an array) for discussion of delete vs delete[].