Standard compliant custom allocator
Is OK to throw an exception when 0 is passed to allocate method?
Thank you.
P.S.
If n == 0, the return value is unspecified.
Does it mean that allocate shouldn't throw an exception? I am inclined to think that if throwing wasn't allowed for n==0, then the 开发者_运维百科standard would clearly spell it out.
All the standard has to say (§20.1.5/2) is that given
- T– any type
- X– an Allocator class for type- T
- a– a value of type- X&
- n– a value of type- X::size_type,
the return value of the expression a.allocate(n) is unspecified if n equals 0.
One one hand, given that X::allocate doesn't have any mandated exception specification and explicitly may throw std::bad_alloc, I don't see why it couldn't throw some other type of exception as well. On the other hand, the wording specifically calls out the condition wherein n equals zero and directly implies that there is a return value, meaning you shouldn't throw. I think it may be open to some interpretation, but personally I'd side with the latter and consider it an unexceptional code-path.
The standard demands that an allocation of size 0 shall return a pointer to a memory block of 1 byte size, Brb, looking for relevant standards paragraph.
Edit:
First, I only got the FDIS of C++0x/11 handy (not at home...), but I believe the wording was similar in C++98/03.
Next, it seems I was wrong. It is nowhere stated that the allocator shall return a memory block of size 1. My memory served me wrong. :( Though, I found this little paragraph under 3.7.4.2 [basic.stc.dynamic.allocation] p2:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was subsequently passed to an operator delete. The effect of dereferencing a pointer returned as a request for zero size is undefined.35)
At the end of the same site:
35) The intent is to have operator new() implementable by calling std::malloc() or std::calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.
(Emphasis mine.)
Now, the FDIS says under 17.6.3.5 [allocator.requirements], in a note on allocate:
a.allocate(n)     X::pointer 
Memory is allocated for
nobjects of typeTbut objects are not constructed.allocatemay raise an appropriate exception. [ Note: If n == 0, the return value is unspecified. —end note ]
(Emphasis mine.)
So, you shall not throw, as a return of something is implied by that note. It is, however, not required to return a 1 byte sized memory block. So, to answer your question: No, you are not allowed to throw in allocate when the size request is 0 when implementing a standard compliant allocator.
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论