C++中访问已删除指针触发崩溃,try/catch为何无法捕获?
Great question—this gets to a core detail about C++'s memory model and exception handling that confuses many developers, especially when moving from languages with more managed memory. Let's break this down step by step:
1. C++ try/catch only handles explicitly thrown exceptions
The try/catch mechanism in C++ is designed to catch exceptions that are intentionally thrown with the throw keyword (like throw std::runtime_error("Oops!")). It does not automatically catch low-level memory errors or undefined behavior.
When you access a pointer that's already been freed (a "dangling pointer"), you're triggering what's called undefined behavior (UB). The C++ standard doesn't define what should happen here—it could crash, return garbage values, or even appear to work correctly (the worst case, because it hides the bug).
2. The crash comes from your operating system, not C++
When you free memory with delete or delete[], the operating system reclaims that memory and marks it as unavailable. If your program tries to access that memory later, the OS's memory protection system (like page tables on Unix-like systems or virtual memory protection on Windows) detects this illegal access and kills your program with a segmentation fault (SIGSEGV on Linux/macOS) or access violation error.
This is an OS-level enforcement, not a C++ exception. try/catch has no way to intercept these signals because they're outside the scope of the C++ standard exception model.
3. There's no reliable way to check if a raw pointer is valid
As you noticed, raw C++ pointers don't store any metadata about whether the memory they point to is still allocated. You might try to work around this by setting pointers to nullptr after freeing them:
delete[] a; a = nullptr; // Manually mark as invalid
Then you can check if (a != nullptr) before accessing it—but this is totally dependent on you remembering to do it every time. Even then, there's an edge case: the freed memory could be reallocated to another part of your program, so the pointer isn't nullptr, but it points to memory you no longer own. Accessing that is still undefined behavior.
4. Platform-specific ways to catch these errors (but not standard C++)
If you absolutely need to detect these crashes in your code, some platforms offer non-standard tools:
- On Windows, you can use Structured Exception Handling (SEH) with
__try/__exceptto catch access violations. - On Linux/macOS, you can register a signal handler for
SIGSEGVto catch segmentation faults.
But these are not portable across all C++ compilers and operating systems, so they're not recommended for cross-platform code.
Wrap-up
Raw pointers put all the memory management responsibility on you. Accessing dangling pointers is undefined behavior, and C++'s try/catch won't save you from the OS-level crash that often follows. If you want to avoid these headaches long-term, smart pointers like std::unique_ptr or std::shared_ptr are designed to automatically manage memory and eliminate dangling pointers by default—but it's totally reasonable to master raw pointers first to understand the underlying mechanics.
内容的提问来源于stack exchange,提问作者Andrei Bratu

