std::auto_ptr、delete[] 和泄漏

发布于 2024-07-30 08:47:27 字数 243 浏览 7 评论 0原文

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

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

Why this code does not cause memory leaks?

int iterCount = 1000;
int sizeBig = 100000;
for (int i = 0; i < iterCount; i++)
{
   std::auto_ptr<char> buffer(new char[sizeBig]);
}

WinXP sp2, Compiler : BCB.05.03

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鸵鸟症 2024-08-06 08:47:27

因为你(不)幸运。 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指向的内存。 类似地,删除 p 应该调用 p 上的析构函数,然后释放内存。

char 没有析构函数,因此它只会删除 p 指向的内存。 在我上面的代码中,它不会会破坏数组中的每个元素(因为它没有调用delete[]),因此一些 Foo 会将其本地 bar 变量保留为 un -删除。

Because you're (un)lucky. auto_ptr calls delete, not delete []. This is undefined behavior.

Try doing something like this and see if you get as lucky:

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]);
}

The idea here is that your destructor for Foo will not be called.


The reason is something like this: When you say delete[] p, the implementation of delete[] is suppose to go to each element in the array, call its destructor, then free the memory pointed to by p. Similarly, delete p is suppose to call the destructor on p, then free the memory.

char's don't have a destructor, so it's just going to delete the memory pointed to by p. In my code above, it is not going to destruct each element in the array (because it's not calling delete[]), so some Foo's will leave their local bar variable un-deleted.

七婞 2024-08-06 08:47:27

auto_ptr 仅在循环迭代期间有效,并在迭代完成时释放与其连接的对象。

编译器可以看到,在这种情况下 new[] 可以以与 new 相同的方式分配空间 - 无需在任何地方存储元素数量,因为不需要调用琐碎的 < code>char 析构函数 - 这就是为什么稍后当 auto_ptr 的析构函数调用 delete 而不是 delete[] 时,它不会导致任何问题,因为内存块实际上已经以new的方式分配,并且该分配可以与删除配对。

这是一个不该做的事情的例子。 由编译器决定是否用 new 替换 new[]。 使用delete而不是delete[],反之亦然是未定义的行为。

请参阅 你为什么要写一些东西像这样? (故意不在数组上使用delete [])讨论deletedelete[]

The auto_ptr will only live for the duration of the loop iteration and will release the object connected to it on iteration completion.

The compiler can see that in this case new[] can allocate space in the same way as new - without storing the number of elements anywhere since there's no need to call trivial char destructors - and that's why later when delete is called by the auto_ptr's destructor instead of delete[] it causes no problems since the memory block has actually been allocated in the new's way and that allocation can be paired with 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[].

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文