Can new throws in a case of heap corruption?
Asked Answered
E

4

9

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 happen. Is this correct?

Eelgrass answered 6/7, 2011 at 7:17 Comment(5)
Is this a OS specific question? If yes, I'll edit the questionAlroy
if it's undefined behaviour, anything can happen. It can start nethack. Or it can throw exception. Programmers shouldn't rely on that behaviour in their programs though. Worst case is that the error is not found before you need to port it to another compiler/platform which implements the UB differently.Guthrun
FWIW, I have seen new fail due to heap corruption. Doesn't mean it always will, of course, but it can. (what it actually will do depends on how the heap is implemented, what parts of the heap got corrupted, and how)Digestion
@Tony: You should put that as an answer :)Ahimsa
@tp1: I'd like to see an implementation that starts up a version of nethack that's specifically written such that the way the game is played would provide a definition for the undefined behavior. And it would be consistent for whatever caused that undefined behavior for the remainder of program execution, with the option of keeping it for future executions of the program.Kreis
W
6

( 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 a reintrepet_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..
  • Application data

    • Objects the application itself has created via new and new[] may be damaged, corrupting the program state, pointers and handles they contain etc.. Problems could manifest in any number of ways.

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.

Wingspread answered 6/7, 2011 at 8:27 Comment(1)
My +1 for an ellaborated explanation :)Ahimsa
S
8

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.

Splinter answered 6/7, 2011 at 7:27 Comment(0)
W
6

( 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 a reintrepet_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..
  • Application data

    • Objects the application itself has created via new and new[] may be damaged, corrupting the program state, pointers and handles they contain etc.. Problems could manifest in any number of ways.

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.

Wingspread answered 6/7, 2011 at 8:27 Comment(1)
My +1 for an ellaborated explanation :)Ahimsa
C
5

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!

Clytemnestra answered 6/7, 2011 at 7:30 Comment(0)
L
3

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.

Ljubljana answered 6/7, 2011 at 7:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.