7

为什么这段代码不会导致内存泄漏?

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

4

2 回答 2

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's 没有析构函数,所以它只会删除 p 指向的内存。在我上面的代码中,它不会破坏数组中的每个元素(因为它没有调用delete[]),所以一些 Foo 将保留其本地 bar 变量未删除。

于 2009-07-29T07:35:16.487 回答
3

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[].

于 2009-07-29T07:35:21.773 回答