3

I am learning c++ using tutorials from http://www.learncpp.com. In the lesson on Dynamic memory allocation with new and delete (http://www.learncpp.com/cpp-tutorial/69-dynamic-memory-allocation-with-new-and-delete/), it states:

Similarly, when a dynamically allocated variable is deleted, the pointer pointing to it is not zero’d. Consider the following snippet:

int *pnValue = new int;
delete pnValue; // pnValue not set to 0

if (pnValue)
    *pnValue = 5; // will cause a crash

However, when I try it (compiler: GNU GCC compiler, ubuntu), my program doesn't crash.

int *pnValue = new int;
delete pnValue; // pnValue not set to 0
if (pnValue)
    *pnValue = 5; // will cause a crash -> doesn't
std::cout << "Did not crash" << std::endl;

What is happening here? Is there any form of runtime checking in C++?

plafer
  • 185
  • 12
  • 1
    The key phrase in that tutorial is : *...this **almost inevitably** will cause a program to crash** - emphasis mine. Perhaps it should add *eventually* to that sentence. – J... May 10 '15 at 15:50
  • 2
    `Is there any form of runtime checking in C++` Not for this, and for most other things (such as out-of-bounds array accesses and similar mistakes). You have to write the code carefully so that you don't make these mistakes. – PaulMcKenzie May 10 '15 at 15:58
  • 2
    That site is doing a good job of teaching C++ for the 20th century. – n. m. could be an AI May 10 '15 at 16:03
  • 1
    Re *will cause a crash* -- There's no guarantee of that. There's no telling what will happen when you assign to that memory location. The behavior is undefined. – David Hammen May 10 '15 at 16:20
  • 1
    This code will **almost certainly not** crash. But if it does, it will **almost inevitably** be in a very surprising way, in an unrelated part of the program, and hard to debug. BTW there are tools like `valgrind` that help you find such bugs. – anatolyg May 10 '15 at 16:22

3 Answers3

9

Your program doesn't crash because you are lucky (or unlucky, thanks @user1320881, since you may not detect such things in more complicated code, and some later crashes or nasty side effects may happen). In fact, what you have here is undefined behaviour, and anything can happen (not necessarily a crash). Technically, your program doesn't crash probably because the operating system didn't yet reclaim that part of the memory and you don't overwrite memory that belongs to some other process, but you shouldn't write such code ever.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • 7
    I'd consider it 'unlucky' :) - Would be better if it crashed so you catch the error. – Unimportant May 10 '15 at 15:49
  • A much more likely reason for a program to crash after this operation is corrupted heap meta data. A lot of allcators will store control structures such as linked list pointers in the freed chunk. – Niklas B. May 10 '15 at 18:24
2

Welcome to undefined behavior in C++. Though your question has already been directly answered, since you are new to the language I'd recommend John Regehr's blog post the C++ Super-FAQ entry about the subject. I believe they will clarify a lot of later questions that you may have.

Tanz87
  • 1,111
  • 11
  • 10
1

EDIT: after couple of comments - the short answer - and perhaps the best - is that the behaviour is undefined.

C++ does not enforce the pointer to NULL after delete, so the pointer might still have and most likely does have the memory reference to the deallocated memory.

If the memory reference does exist, there is no NULL pointer exception it may not crash because what you do with the memory referenced goes unnoticed.

The Operating system doesn't notice the invalid reference, as long as you are just using with memory allocated for your process in the heap. It would crash, if delete operation would deallocate some of the operating system memory reserved for heap, but that's unlikely event.

The C++ library's heap manager may not notice the access to deallocated memory - this is implementation dependent.

Your own program may not be affected either, because you haven't yet done allocations that might reuse the memory you just deallocated.

The C++ compiler doesn't notice this - nor does it enforce run-time reference counting for the memory allocated objects, nor does it perform any run-time checking for validity of the references. The compiler is just happy you assigned a variable of correct type to the memory referenced by the pointer

With C++ the memory allocations are not only hard to manage but also may cause very serious problems. This is why reference counting is a good practice and it can be used also with C++ with libraries dedicated to it.

Community
  • 1
  • 1
Tero Tolonen
  • 4,144
  • 4
  • 27
  • 32