9 c++ out-of-memory new-operator dynamic-memory-allocation
我是一名学生,我对C++知之甚少,我试图扩展它.这更像是一个哲学问题.我不是想要实现某些东西.
以来
#include <new>
//...
T * t = new (std::nothrow) T();
if(t)
{
//...
}
//...
Run Code Online (Sandbox Code Playgroud)
将隐藏异常,并且因为与简单相比处理异常更重if(t),为什么不正常new T()不被认为是不太好的做法,考虑到我们将不得不try-catch()用来检查简单分配是否成功(如果我们不成功,只是看程序死了)?
new与使用nothrow new?相比,正常分配有哪些好处(如果有的话)?在这种情况下,例外的开销是微不足道的?
此外,假设分配失败(例如,系统中不存在内存).程序在那种情况下可以做什么,或者只是优雅地失败.当保留所有内存时,无法在堆上找到空闲内存吗?
如果分配失败,并且a std::bad_alloc为thrown,我们如何假设由于没有足够的内存来分配对象(例如a new int),将有足够的内存来存储异常?
谢谢你的时间.我希望这个问题符合规则.
由于处理异常比简单的if(t)更重,为什么不正常的新T()不被认为是不太好的做法,考虑到我们将不得不使用try-catch()来检查简单的分配是否成功(如果我们不这样做,只看程序死掉)?与使用nothrow new相比,正常新分配有哪些好处(如果有的话)?在这种情况下,例外的开销是微不足道的?
使用异常的代价确实非常沉重,但(在一个经过适当调整的实现中)只会在抛出异常时支付惩罚- 因此主线情况保持非常快,并且两者之间不可能有任何可测量的性能.你的榜样.
异常的优点是代码更简单:如果分配多个对象,则不必"分配A; if(A){分配B; if(B)等......".在例外和主线情况下的清理和终止最好由RAII自动处理(而如果你手动检查,你也必须手动释放,这使得内存泄漏太容易了).
此外,假设分配失败(例如,系统中不存在内存).程序在那种情况下可以做什么,或者只是优雅地失败.当保留所有内存时,无法在堆上找到空闲内存吗?
它可以做很多事情,最好的办法取决于正在编写的程序.失败和退出(优雅或其他)当然是一种选择.另一种方法是提前预留足够的内存,以便程序可以继续其功能(可能具有降低的功能或性能).它可能能够释放一些自己的内存(例如,如果它保留了可以在需要时重建的缓存).或者(在服务器进程的情况下),服务器可能拒绝处理当前请求(或拒绝接受新连接),但保持运行以便客户端不会丢弃其连接,并且一旦内存可以再次开始工作回报.或者在交互式/ GUI应用程序的情况下,它可能会向用户显示错误并继续(允许他们修复内存问题并重试 - 或者至少保存他们的工作!).
如果分配失败,并抛出std :: bad_alloc,我们怎么能假设因为没有足够的内存来分配一个对象(例如一个新的int),就会有足够的内存来存储异常?
不,通常标准库通常会事先通过分配少量内存来确保在内存耗尽时会有足够的内存来引发异常.
Nothrow被添加到C++主要是为了支持想要编写无异常代码的嵌入式系统开发人员.如果您实际上想要在本地处理内存错误作为比malloc()后面的placement new更好的解决方案,这也很有用.最后,对于那些希望继续使用(当时是最新的)基于检查NULL的C++编程样式的人来说,这是必不可少的.[我自己提出了这个解决方案,我提出的少数几个没有被投票的事情之一:]
仅供参考:在内存不足时抛出异常非常敏感且难以实现,因为例如,如果您要抛出一个字符串,则可能会因为字符串进行堆分配而导致错误.实际上,如果由于堆崩溃而导致内存不足,您甚至可能无法创建临时堆!这个特殊情况解释了为什么标准异常受到相当限制.此外,如果你在本地公平地捕获这样的异常,为什么你应该通过引用而不是值来捕获(以避免可能的副本导致双重错误).
因此,nothrow为关键应用程序提供了更安全的解决方案.
| 归档时间: |
|
| 查看次数: |
4354 次 |
| 最近记录: |