Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
489 views
in Technique[技术] by (71.8m points)

c++ - Do Standard Library (STL) Containers support a form of nothrow allocation?

The new operator (or for PODs, malloc/calloc) support a simple and efficient form of failing when allocating large chunks of memory.

Say we have this:

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;
}
...

Is there any such construct for the std::containers, or will I always have to handle an (expected!!) exception with std::vector and friends?


Would there maybe be a way to write a custom allocator that preallocates the memory and then pass this custom allocator to the vector, so that as long as the vector does not ask for more memory than you put into the allocator beforehand, it will not fail?


Afterthought: What really would be needed were a member function bool std::vector::reserve(std::nothrow) {...} in addition to the normal reserve function. But since that would only make sense if allocators were extended too to allow for nothrow allocation, it just won't happen. Seems (nothrow) new is good for something after all :-)


Edit: As to why I'm even asking this:

I thought of this question while debugging (1st chance / 2nd chance exception handling of the debugger): If I've set my debugger to 1st-chance catch any bad_alloc because I'm testing for low-memory conditions, it would be annoying if it also caught those bad_alloc exceptions that are already well-expected and handled in the code. It wasn't/isn't a really big problem but it just occurred to me that the sermon goes that exceptions are for exceptional circumstances, and something I already expect to happen every odd call in the code is not exceptional.

If new (nothrow) has it's legitimate uses, the a vector-nothrow-reserve also would have.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

By default, the standard STL container classes use the std::allocator class under the hood to do their allocation, which is why they can throw std::bad_alloc if there's no memory available. Interestingly, the C++ ISO specification on allocators states that the return value of any allocator type must be a pointer to a block of memory capable of holding some number of elements, which automatically precludes you from building a custom allocator that could potentially use the nothrow version of new to have these sorts of silent allocation failures. You could, however, build a custom allocator that terminated the program if no memory was available, since then it's vacuously true that the returned memory is valid when no memory is left. :-)

In short, the standard containers throw exceptions by default, and any way you might try to customize them with a custom allocator to prevent exceptions from being thrown won't conform to the spec.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...