Can new throws in a case of heap corruption?
In a case of a heap corruption, can new
throw?
If I understand it correctly, in a case of a heap corruption, all bets are off, and anything can 开发者_如何学Gohappen. Is this correct?
Yes, if the heap is corrupted, anything can happen. Throwing an exception is possible, but unlikely. What's more likely is that it will start trashing memory; if you're lucky, you'll just get a GPF/Segmentation fault. If you're unlucky, your program will continue running with a corrupt heap.
( Moved from a comment to an answer at Als' suggestion, and extended for better or worse :-) )
A corrupted heap invalidates any behavioural expectations you may have of the program. Crucially, throwing an exception implies some reliable programmatic handling is possible, but no implementation detecting heap corruption could possibly know whether that's true or not, therefore they're much more likely to assert
or similar.
If we consider what types of corruption a heap may have:
Corrupt records related to the current state of the heap.
- Allocation and/or free lists. Corruption might mean later heap allocations dereference invalid pointers, that some part of the heap is leaked wholesale, that a later heap-allocation or deallocation algorithm invoked during
new
/new[]
/delete
/delete[]
/malloc
/realloc
/free
loops infinitely etc.. - Synchronisation objects. The state of mutexes, condition variables etc. used by the implementation of the heap routines may be corrupted, leading to deadlocks, race conditions, later failures during related function calls.
- Counters recording the number of array elements constructed by
new[]
: corruption implies delete[] will destruct the wrong number of elements. If the number is reduced, some objects won't be destructed, potentially causing leaks of memory they contained pointers to, failure to decrement reference counters, file handles left open, mutexes left locked, shared memory segments not destroyed etc.. If the number increases,delete[]
is likely to access past the memory containing the array - possibly causing SIGSEGV - calling destructors equivalent to areintrepet_cast<>
of the memory content as the object to be destroyed. That might try to dereference/delete/free invalid pointers, close "random" file handles etc..
- Allocation and/or free lists. Corruption might mean later heap allocations dereference invalid pointers, that some part of the heap is leaked wholesale, that a later heap-allocation or deallocation algorithm invoked during
Application data
- Objects the application itself has created via
new
andnew[]
may be damaged, corrupting the program state, pointers and handles they contain etc.. Problems could manifest in any number of ways.
- Objects the application itself has created via
More generally regarding the heap, at very best you can hope that new will throw when heap is exhausted, but even that's far from guaranteed - particularly on O.S.s where only virtual memory is allocated by new
, and if later page faults can't be satisfied they manifest as SIGSEGV or similar.
Heap corruption is an undefined behavior. new
may throw
or it may not. Memory allocator is ultimately a code which reads the heap memory and allocates memory or prompts that there is no memory available. Now if the reading pane is corrupted then, things go crazy!
new
relies on some memory allocator, depending on the implementation. It could be malloc, HeapAlloc (for example), or whatever someone has defined on the operator new you happen to use. So the question is really how the allocator used by new
behaves when its data structure gets corrupted. And that, of course, is implementation dependent.
精彩评论