2

I faced some crash at delete(). I try to wrap delete() with try-catch and handle it properly but I still have crash instead of fall into catch section.

Here is example example of what I try to do.

int *i = new int();
delete (i);
try {
    delete (i);
}catch (...) {
    std::cout << "Oops";
}

The questions is "why I can't catch it in such way?" and "how I can properly catch situation like this?".

Stepan Loginov
  • 1,667
  • 4
  • 22
  • 49
  • What compiler/OS do you use? – Ari0nhh May 17 '17 at 11:20
  • You might want to look http://stackoverflow.com/questions/43074727/a-pointer-that-can-point-to-anywhere-how-to-determine-if-delete-can-be-safely/43077127#43077127 here. The question is similar to yours. – Sniper May 17 '17 at 11:33
  • Use std::unique_ptr! –  May 17 '17 at 11:54
  • 1
    In C++11 there's almost never a reason to call `new`, and absolutely, positively no reason whatsoever to call `delete`. You are trying to fix the symptoms that stem from using C++ in a way that was common almost two decades ago. We have since moved forward and access to better tools (e.g. `std::unique_ptr` and `std::make_unique`). – IInspectable May 20 '17 at 07:22

3 Answers3

7

The delete operator does not throw exceptions:

Exceptions (none) (until C++11)

noexcept specification: noexcept (since C++11)

cf cppreference.

A double delete is a programming error. You should not try to handle it: use debugging tools to get rid of them (and better memory management with RAII and the standard class that use RAII)

Community
  • 1
  • 1
nefas
  • 1,120
  • 7
  • 16
  • Note that double deletion is Undefined Behavior. In other words, anything may happen, and "anything" includes a `noexcept` function throwing an exception ! Still, the conclusion is correct: don't handle it, prevent it. (+1) – MSalters May 17 '17 at 11:39
  • 1
    a noexcept function throwing an exception will call std::terminate() (which by default call std::abort) – nefas May 17 '17 at 11:45
  • That's the specific rule, but the Undefined Behavior rule trumps every other rule. – MSalters May 17 '17 at 11:49
  • I agree, but would delete throw an exception (which it shouldn't since delete specification say it shouldn't) std::terminate would be called (with post C++11 code). So there is no way (even if some UB would cause delete to throw an exception) that you could handle double delete with a catch. But in the end, I agree with you, once UB are out, the rest does not matter much. – nefas May 17 '17 at 11:56
2

delete is a no exception operation, so you won't be able to catch it.

George Newton
  • 788
  • 8
  • 12
-2

Use a variable in the stack to store whether or not the variable was deleted. If you can't do that, then try using realloc instead of delete.

AppWriter
  • 247
  • 2
  • 13
  • How do you plan to get rid of _that_ variable? You need a third variable to keep track of whether the second one is deleted. And then a fourth... – MSalters May 17 '17 at 11:40
  • @MSalters I plan to use a stack variable, which will automatically get deleted when the program exits. – AppWriter May 17 '17 at 11:42
  • that would be a global variable. And the problem is, _which_ global variable would you use? A linked list of items might have thousands of nodes, all allocated with `new`, and you often won't know up front how many. Besides, if you did, why didn't you make that list a global? – MSalters May 17 '17 at 11:53
  • Never ever use realloc in C++. –  May 17 '17 at 11:58
  • At some point, it become easier to create your own allocator where a double delete is a no-op. – nefas May 17 '17 at 13:12