Why not catch a segmentation error in this case?

#include <iostream> int main(int argc, char* argv[]) { int* ptr = new int(47); std::cout << ptr << " " << *ptr << std::endl; /* Память выделенная в heap'e должна вернуться системе. Или она будет доступна программе до окончания области видимости указателя ? */ delete ptr; *ptr = 74; std::cout << ptr << " " << *ptr << std::endl; } 

3 answers 3

Deleting an invalid pointer leads to undefined behavior — you can't write to C ++ like that.

"Undefined behavior" does not mean that the program will fall out with an error. In this state, the program can do anything , including working as the programmer wants.

Allowing undefined behavior in the program is prohibited.

  • one
    The phrase "including, and work in accordance with its specification" I would replace it with some other construction, because the specification assumes an indefinite behavior, and here it is rather meant "what the programmer meant" or "ignoring the problem." - Athari
  • @Discord Here "specification" is understood here - "what the programmer wants from the program". - gbg
  • I understand the meaning, but this wording creates confusion. - Athari
  • How to formulate it ... It turns out too much in the military - "it is impossible, because it is said so." But, generally speaking, when discussing this issue by the committee it was clearly considered why it was decided that way. It seems to me that the explanation of why does not interfere. You shouldn’t make a black box out of the system and forbid something simply because it’s supposed to be :) - Harry

How does a memory manager usually work? Initially, there is a large chunk of memory that you can work with, and which is marked as free. When requested, the manager can, for example, allocate a piece of memory and keep a note in his internal list - this memory is allocated, do not touch it ... (in fact, this is a separate and very serious topic, but such an idea will suffice for explanation) . The block is released - the manager makes a corresponding mark on himself. Most likely, in front of the block there will be a small block with service information - about employment, the size of the occupied block, etc.

What happens when you release with the memory itself? Nothing. It is simply marked as free. Only the information in the service fields is changing.

Therefore, you can write there information. Or take it.

But even if you do it right after being released, without intermediate actions - no one can guarantee you the correctness of this action: what if the same manager writes his official information to this place, so you just spoil it? Or another thread will have time to capture this memory yourself? Nobody knows what exactly will happen, so about such situations it is said - “indefinite behavior”.

In short, getting a program crash in such a situation is more like luck. Bad luck - not to get any error, but to mess up the memory, and then, after 15 minutes of the program's work, get into trouble - for example, a completely incorrect value of a variable that you seem to have saved as something completely different. And then for a long time - to look for a mistake for a very long time, which is located in a completely different place of the program, and it also does not reproduce completely at every launch ...

  • 2
    Usually memory managers don't work at all like that :) - ixSci
  • one
    @Harry - replacing knowledge with conjectures in programming leads further to a "mystical" attitude towards the machine and the programs working in it. You either know how something works - you read the source code, visited the textbook, read the book, or treat this entity as a black box. - gbg
  • one
    @ixSci "Totally"? In my opinion, the abstraction "a memory manager somewhere somehow stores information about what memory is allocated / free, and releasing a memory block often does not make the block unavailable or destroy data in it" has a right to exist. Description of the details is true a few inside out, but what's the difference ... - Athari
  • @gbg I can not think of a situation where the discrepancy described with reality can lead to a misunderstanding of what is happening. The perception of the memory manager as a black box still remains, but the "WTF" reaction to the one described in the question does not occur - it is already progress. - Athari
  • @Discord Considering that you also posted a response consisting of conjectures, I am not surprised. You have some kind of "operating system" there, some kind of "blocks". A C ++ program can run on bare hardware, where there is no operating system; can work with memory like XMS, where access takes place through a 64-kilobyte pane, and so on. Composing myths and legends about what happens in UB time is a waste of time. The answer to the author's question - "you have created UB". That's why it is UB that it is impossible to describe what is happening without conjectures. - gbg

When you release a block of memory, and then work with it, anything can happen. “Anything” includes:

  • The memory block could have been placed by the memory manager on the free list. The data in the block itself is usually not overwritten, so when accessing the "remote" memory, it will still contain the information you need.

  • If you are using debug mode or some kind of error protector, then the memory manager could intentionally wipe the data in the freed block. As a result, when reading the data, you obviously get garbage.

  • The released block of memory or its part could be given by the memory manager to some other piece of your code. The content could accordingly be overwritten by this other piece of code. The data you read, but interpret incorrectly, so for you it will be garbage.

  • The memory manager could decide to give an unnecessary page of memory along with your block to the operating system. When you try to access the "hole" you get an access error, and your process will crash.

The nuance is that the operating system works with large blocks of memory, and your program wants small ones, so the memory manager will request large pieces from the axis, and then deal with the distribution of small pieces in large pieces independently. When you release a small piece, it’s not at all the fact that the memory manager will free a large piece that contains your small one.