真的有必要在这个指针上调用删除吗?

Is it really necessary to call delete on this pointer

本文关键字:调用 删除 指针 真的      更新时间:2023-10-16

我有一个指向一个非常大的静态对象数组的指针,这些对象没有任何析构函数,也没有从任何类继承。此数组在程序开始时分配,并且永远不会再次分配/重新定位(根据设计(。只有在程序的最后才需要销毁此数组。我真的需要为阵列调用删除,还是可以让操作系统 (Windows( 清理?删除程序会延迟退出程序 5-10 秒。如果不调用删除,操作系统将为我们执行此操作,程序将立即退出。

一般来说,让 os 清理是一个坏主意。
我假设不会发生任何坏事,但是将来您可能会在另一个程序中使用您的代码,并且您将不得不更改内容。

底线 - 释放您分配的所有内容。

您应该释放它;原因如下:

  • 它很容易,而且只需最少的努力
  • 它的良好做法。太频繁地走捷径会在某个时候咬你
  • 它为阅读您的代码的其他人树立了榜样
  • 它可以保护您免受问题的影响。信任操作系统来清理它意味着您信任应用程序可以正常退出。如果没有发生这种情况,内存释放将停止
  • 它可以保护您免受自己的伤害:将来您可能会在硬件设备中保留内存。操作系统可能无法释放此功能。所以要明确的是:并非所有内存总是作系统释放。

。这些只是清理烂摊子的一些原因;-(...此外。。。你可能想把这些东西放在一个实际的类中。然后,清理代码已经存在。

另请注意:不释放内存是最常见的运行时问题之一。只是因为这个原因,对它严格要求是明智的。

No.如果可以假定程序在现代操作系统中运行,则不必在关闭时释放分配。如果它显着减少了关闭程序的时间,则可能是值得考虑的选择。

但是,不释放分配确实存在内存泄漏检测工具将检测到此故意泄漏的缺点,从而使其使用出现问题。作为解决方案,我建议使泄漏切换可切换,以便您可以使用检测工具运行非泄漏版本,并在生产中使用泄漏版本。

是的,但不是出于您认为的原因。

尽管总的来说,这有点违反"良好实践",但退出并让操作系统清理是完全"可以的",因为没有什么可做的。诸如"这是一个坏主意,邪恶的事情可能会发生,资源哦,灾难,等等"之类的反对意见是没有充分根据的,因为真正发生的事情是你的进程不复存在,操作系统为其分配的内存页也是如此,仅此而已。因此,只要你 100% 肯定你的析构函数中不需要发生任何事情,就没有理由进行分配,除了让像 valgrind(和审计员,如果适用的话(这样的工具满意。

但是operator delete[]需要 5-10 秒的事实表明情况并非如此。那里确实发生了一些事情。

在我的桌面上,删除数百万个对象几乎需要"零"时间,只要析构函数不是非常不平凡。我说的是"非常非常不平凡"这样有趣的事情,因为琐碎(和非平凡(析构函数是一个术语,意思是非常具体的东西,事实上,"不是非常非常不平凡">的非平凡析构函数调用仍然非常快。

写了一个快速的 15 行进行测试。使用一些数据、默认构造器零初始化数据和简单的析构函数进行结构定义。一个main函数,它分配 1 亿个对象,迭代数组并使用argc的值更新每个元素(以防止编译器优化整个元素(,最后删除数组。

整体运行时间:0.2 秒,或占用 50 毫秒。相同的程序,但使用有条件地更新全局计数器的非平凡析构函数总共需要 0.3 秒。请注意,这包括分配、构造和迭代。

所以,显然你正在做一些一点也不微不足道的事情。对子对象进行大量嵌套的虚拟析构函数调用?从对象的析构函数中解除分配?清零或以其他方式接触千兆字节的内存?关闭文件句柄?无法说出是什么,但一定有什么事情正在发生,否则不会花这么长时间。

所以。。。,就这样退出是不行的。因为有些事情正在发生,如果你跳过删除,它就不会发生。