C++ 我们为什么要删除由new分配的内存?

C++ 我们为什么要删除由new分配的内存?,c++,garbage-collection,C++,Garbage Collection,据说new分配的内存应该通过delete释放,但是现代桌面操作系统将回收内存,即使您不删除它。那么,我们为什么要删除由new分配的内存呢 另外,assert被称为不调用析构函数,它似乎在STL中被广泛使用(至少VS2015可以做到这一点)。如果建议删除由new分配的内存(像string、map和vector这样的类使用析构函数删除分配的内存),那么为什么开发人员仍然使用大量assert呢?如果不删除,就会导致内存泄漏。每次调用此运算符时,进程都会浪费部分地址空间,直到最终耗尽内存。如果不删除,则

据说
new
分配的内存应该通过
delete
释放,但是现代桌面操作系统将回收内存,即使您不
删除它。那么,我们为什么要
删除
由new分配的内存呢

另外,
assert
被称为不调用析构函数,它似乎在STL中被广泛使用(至少VS2015可以做到这一点)。如果建议
删除
new
分配的内存(像
string
map
vector
这样的类使用析构函数删除分配的内存),那么为什么开发人员仍然使用大量
assert
呢?

如果不删除,就会导致内存泄漏。每次调用此运算符时,进程都会浪费部分地址空间,直到最终耗尽内存。

如果不删除,则会导致内存泄漏。每次调用此运算符时,进程都会浪费部分地址空间,直到最终耗尽内存

据说
new
分配的内存应该由
删除
,但现代桌面操作系统将回收内存,即使 你不能
删除它。那么,我们为什么要
删除
分配的内存呢
通过
新建

小心!只有在程序完成后,操作系统才会回收内存。这与Java或C#中的垃圾收集不同,后者在程序运行时释放内存

如果您不
delete
(或者更准确地说,如果您不确保
delete
std::unique_ptr
std::string
std::vector
等资源管理类调用,那么内存使用将继续增长,直到内存耗尽

更不用说析构函数不会运行,如果您有析构函数执行的不仅仅是释放内存的类型的对象,这一点很重要

另外,
assert
被称为不调用析构函数

更准确地说,
assert
会导致程序以不调用析构函数的方式终止,除非相应的翻译单元是使用定义的
NDEBUG
预处理器宏编译的,在这种情况下,
assert
不会执行任何操作

而且它似乎在STL中得到了广泛的应用(至少VS2015做到了这一点)

是的,Visual C++ 2015的标准库实现有很多。您还应该在自己的代码中自由地使用它来检测bug

C++标准本身没有指定如何以及如果代码> Asjt>/Cult>S应该出现在标准库函数的实现中。它确实规定了程序行为未定义的情况;这些通常对应于库实现中的

assert
(这是有意义的,因为如果行为没有定义,那么实现可以自由地做任何事情,那么为什么不以一种有用的方式使用这种自由来检测bug呢?)

如果建议
删除
new
分配的内存(如
字符串
映射
向量
使用析构函数删除分配的 内存),那么为什么开发人员仍然使用大量的
assert

因为如果断言失败,那么您希望程序立即终止,因为您检测到一个bug。如果您检测到一个bug,那么根据定义,您的程序处于未知状态。通过运行析构函数允许程序在未知状态下继续运行可能是危险的,并且可能会损害系统完整性和数据一致性

毕竟,正如我上面所说,析构函数可能不仅仅调用
delete
几次。析构函数关闭文件、刷新缓冲区、写入日志、关闭网络连接、清除屏幕、加入线程或提交或回滚数据库事务。析构函数可以做很多事情,这些事情可能会修改并破坏系统资源

据说
new
分配的内存应该由
删除
,但现代桌面操作系统将回收内存,即使 你不能
删除它。那么,我们为什么要
删除
分配的内存呢
通过
新建

小心!只有在程序完成后,操作系统才会回收内存。这与Java或C#中的垃圾收集不同,后者在程序运行时释放内存

如果您不
delete
(或者更准确地说,如果您不确保
delete
std::unique_ptr
std::string
std::vector
等资源管理类调用,那么内存使用将继续增长,直到内存耗尽

更不用说析构函数不会运行,如果您有析构函数执行的不仅仅是释放内存的类型的对象,这一点很重要

另外,
assert
被称为不调用析构函数

更准确地说,
assert
会导致程序以不调用析构函数的方式终止,除非相应的翻译单元是使用定义的
NDEBUG
预处理器宏编译的,在这种情况下,
assert
不会执行任何操作

而且它似乎在STL中得到了广泛的应用(至少VS2015做到了这一点)

是的,Visual C++ 2015的标准库实现有很多。您还应该在自己的代码中自由地使用它来检测bug

C++标准本身没有指定如何以及如果代码> Asjt>/Cult>S应该出现在标准库函数的实现中。它确实规定了程序行为未定义的情况;这些通常对应于库实现中的

assert
(这是有意义的,因为如果行为仍然未定义)
int main(){
    int* x = new int(1);
}
int main(){
    while ( someCondition ) {
        Foo* x = new Foo();
        doSomething(*x);
    }  // <- already here we do not need x anymore
}     
int main(){
    while ( someCondition ) {
        Foo x;
        doSomething(x);
    }  // <- memory for x is freed automatically
}