【发布时间】:2011-06-17 03:28:02
【问题描述】:
new 运算符(或对于 POD,malloc/calloc)在分配大块内存时支持一种简单而有效的失败形式。
假设我们有这个:
const size_t sz = GetPotentiallyLargeBufferSize(); // 1M - 1000M
T* p = new (nothrow) T[sz];
if(!p) {
return sorry_not_enough_mem_would_you_like_to_try_again;
}
...
std::containers 是否有任何这样的构造,或者我是否总是必须处理 std::vector 和朋友的(预期的!!)异常?
可能有一种方法可以编写一个自定义分配器来预分配内存,然后将此自定义分配器传递给向量,这样只要向量不要求比您预先放入分配器中更多的内存,它不会失败?
事后考虑:除了正常的储备函数之外,真正需要的是成员函数bool std::vector::reserve(std::nothrow) {...}。但是,由于只有在分配器也被扩展以允许 nothrow 分配时,这才有意义,所以它不会发生。似乎 (nothrow) new 毕竟对某些东西有好处:-)
编辑:至于为什么我什至在问这个:
我在调试时想到了这个问题(调试器的第一次机会/第二次机会异常处理):如果我将调试器设置为第一次机会捕获任何 bad_alloc,因为我正在测试低内存条件,它会如果它还捕获了那些已经在代码中很好预期和处理的 bad_alloc 异常,那会很烦人。这不是/不是一个真正的大问题,但我只是突然想到,异常是针对特殊情况的,而我已经预料到代码中每个奇怪的调用都会发生的事情并不例外。
如果new (nothrow) 有它的合法用途,那么向量-nothrow-reserve 也将有。
【问题讨论】:
-
写一个
try...catch结构没什么大不了的。如果你有很多,你可以写一个包装函数template<typename T> T* MyAlloc (size_t),里面有异常处理。 -
有时这很重要。
-
即使您分配千兆字节并接近 OOM?我对此表示怀疑。
-
@Martin:你能解释一下为什么你不希望抛出任何异常吗?这对我来说毫无意义。
-
@TonyK:你问我为什么要这个是完全正确的。我故意不考虑这个问题,因为那样我会得到质疑我的动机的答案,而不是专注于实际问题的东西。 :-)(我将添加一个编辑解释更多内容。)
标签: c++ stl standard-library