To my understanding,
try/catch
only catches
C++ exceptions. Those may be thrown from your own code, from third-party C++ libraries, or, in some cases, from the C++ standard library. Any C++ code that explicitly invokes a
throw
statement. But there are many "error conditions" – such as
access violation or
division by zero – that do
not trigger a C++ exception, and therefore will
not be caught by
try/catch
.
Microsoft Windows uses
structured exceptions to report certain error conditions, including
access violation,
division by zero,
illegal instruction and so on. Those are totally separate from C++ exceptions and they work in plain C and even other languages. They are more like
signals in Linux/Unix. You can catch structured exceptions by using the
MSVC-specific __try/__except
mechanism (doesn't work in GCC). Or by using
SetUnhandledExceptionFilter()
, which will set a callback that is called for all "unhandeled" structured exceptions.
https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record#members
Anyway, if you do anything in your program that is
undefined behavior, then you
may happen to trigger, for example, an
access violation – which in turn may trigger a structured exception (at least on Windows). But there is absolutely
no guarantee that
undefined behavior will trigger an "error", e.g. an exception or abnormal program termination, at all! It could, just as well, happen to "work". Or, even worse, your program may continue running without any observable errors but produce a "bad" (unexpected) result at the end... 🙄
Using delete on a pointer to an object not allocated with new gives unpredictable results. |
So,
delete
'ing a non-null memory address that wasn't allocated with
new
before, or that has already been freed, is
undefined behavior. This means that the
delete
would be "allowed" to crash your application at this point, e.g. via
access violation – but it certainly doesn't
have to! It is possible, just as well, that the "bad"
delete
happens to do nothing. Or that it doesn't crash right away, but messes up the heap space in such a way that
future new
invocations, possibly at a totally unrelated place, will crash unexpectedly; kind of a worst case scenario.
A tool like
Dr. Memory (Windows) or
Valgrind (Linux) can be very helpful here:
https://drmemory.org/page_types.html