[Insight-developers] serious problem with new[] on MSVC++
Charl P. Botha
c.p.botha at ewi.tudelft.nl
Mon, 03 May 2004 22:51:47 +0200
Dear developers,
Brad King wrote:
> Charl P. Botha wrote:
>> It seems that, at least on MSVC, new (or new[]) does not throw an
>> exception when failing to allocate memory[1][2]. Looking at for
>> instance itk::ImportImageContainer::Reserve(), which does all the
>> allocation for itk::Image (and thus for MANY of the ITK filters and
>> sources), the return value of the new[] is not checked!
>>
>> I've seen this crash my applications on windows when working with large
>> DICOM datasets. The program silently continues running, until a filter
>> writes to for example the output Image which has a NULL buffer (due to a
>> failed new[] that wasn't caught).
>>
>> This can be fixed by installing a global new_handler function[3]. I've
>> grepped through the ITK sources and couldn't find an invocation of
>> _set_new_handler(), so I'm assuming no-one has done this.
>>
>> Any discussion (or corrections!) on this is welcome. I'm not sure how
>> new[] indicates failure on for instance the GCC compilers, but whatever
>> the case may be, it's quite critical that this is handled *correctly* in
>> ITK. The ISO C++ spec says that new[] should throw (as far as I can
>> see), but compilers don't always follow this to the letter, as is shown
>> by this example.
>
>
> The C++ standard says that if a new or new[] operator is declared with
> an empty "throw()" specification then it should return NULL when failing
> to allocate memory. Otherwise it should throw a std::bad_alloc exception.
>
> ITK has been written to assume that the exception is thrown and
> therefore never checks the results of allocation (which is the whole
> point of a throwing allocation routine). However, ITK should not set
> anything that is of global process scope since it is a library. The
> application should set the handler correctly if it wants to be robust to
> this problem.
>
> Another alternative is to send all ITK memory allocation through some
> function that tries to use new or new[] to alloate memory and then
> throws std::bad_alloc if it gets a NULL pointer back. That way we can
> be sure the exception will be thrown no matter the default behavior
> provided by a compiler.
Excuse the long quote, but this has been quite a while.
I just got bitten by this one again. It's quite nasty: one's
application simply aborts and after the prerequisite debugging, one
realises that it's because MSVC++ 6.0 sp6 doesn't throw an exception
when a new[] allocation fails. I'm not sure if .NET 2003 does the Right
Thing(tm).
Brad's proposed solution would definitely do the trick: checking the new
or new[] return value and throwing std::bad_alloc in the case of a NULL
in for instance itk::ImportImageContainer (this is where all itk::Image
allocation seems to take place) would do no harm on any of the currently
working C++ compilers, but would make life much easier with compilers
which do not raise exceptions for failing new invocations.
Thanks,
Charl
--
charl p. botha http://cpbotha.net/ http://visualisation.tudelft.nl/