2

In the following code:

int main(int argc,char * argv[]){
  int * ptr;
  ptr = 0; // tried also with NULL , nothing changes
  ptr = new int[10]; // allocating 10 integers
  ptr[2] = 5;
  ptr[15] = 15;  // this should cause error (seg fault) - but it doesn't

  cout << ptr[2] << endl;
  cout << ptr[15] << endl;  // no error here

  delete [] ptr;

  cout << ptr[2] << endl;   // prints the value 5
  cout << ptr[15] << endl;  // prints the value 15
}

The result of the execution is:

5        
15        
5        
15        
  1. How could an element with index number 15 exist, if I'm allocating only 10?
  2. Why do the pointers still have values after the whole array is deallocated?

I tried delete with single allocation like this:

int * ptr;
ptr = 0;
ptr = new int;
*ptr = 5;
cout << *ptr << endl;
delete ptr ;
cout << *ptr << endl;

The result is normal:

5        
0        

Tested with gcc 4.7.2 and gcc 4.1.2 on fedora 17 and another platform (SLC5 - red hat based linux ), in order to make sure it does not depend on the compiler. What am I doing wrong here?

Unihedron
  • 10,902
  • 13
  • 62
  • 72
Miro Rodozov
  • 197
  • 1
  • 10
  • I think, you should read accepted answer [here](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) (question differs a little, but same arguments can be applied) – Lol4t0 Oct 07 '12 at 20:28

3 Answers3

9
  1. The element beyond intended size of array exists, because the memory there happened to exist. Doing anything with it is illegal and leads to the dark unknown.

  2. The deallocation means that the memory isn't allocated for you anymore. It doesn't mean that someone went there and cleaned it up. But accessing what's left of you there is illegal and leads to the dark unknown.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
  • Let me add that `dark unknown` actually means `undefined behaviour`, which is explicitly present in C++ Standard wording. :) – vines Oct 07 '12 at 20:07
  • 1
    Yes ;-) I'd say "called undefined behaviour", because nothing undefined improves the definition enough to make it much less unknown ;-) I just like using non-cliche wording in general — it makes people reinterpret common concepts. – Michael Krelin - hacker Oct 07 '12 at 20:10
  • To 1. This works for me - the point is that my 'users' should not exceed the number of 96 from within ->getElement(int elementNum) and while i was trying with 97 it was returning to me values which was unexpected. So now i'm sure i have to 'make it impossible' to the user To 2. This works for me, since i care only about the memory 'eaten' by the process. I was afraid i'm not cleaning it . – Miro Rodozov Oct 07 '12 at 20:21
  • @MiroRodozov, if you access in any way memory beyond what's officially given to you, you may as will kiss goodbye to your process. Anything can happen and many surprising things too, there's no "works for me". You should either validate index before accessing or some other make sure it's not going beyond boundaries. – Michael Krelin - hacker Oct 07 '12 at 21:05
  • @MiroRodozov: "It works for me" is not a good argument. It must work for anyone. Welcome to the C++ undefined behavior dark side, where unfairness can be compensated by lukyness. C++ does not check array subscripts and index ranges. so it will not refuse your statements. – Emilio Garavaglia Oct 07 '12 at 21:24
  • This was my point - i meant i'll take measures that nobody would possibly write out of the expected scope :) – Miro Rodozov Oct 07 '12 at 21:51
1

You are accessing memory that does not belong to the array. It works because of pure luck. If the program does not crash, it means that you are overwriting parts of memory that belong to your own application, and thus you ruin something somewhere and it can no longer be guaranteed that your program functions correctly.

Mostly you will get a segmentation fault, because you access memory of other applications. This time, you are just 'lucky'. Or as I would call it 'unlucky', because you can't immediately tell from the execution that your program has memory errors.

Ben Ruijl
  • 4,973
  • 3
  • 31
  • 44
  • Thanks this also makes sense. I'll try to 'load' the system with memory consuming programs in order to get my 'expected seg fault'. I was afraid i'm not cleaning my memory as expected. – Miro Rodozov Oct 07 '12 at 20:15
1

Dereferencing a deleted pointer is undefined behaviour as defined by the C++ standard. And it is just that- undefined behaviour. You could crash, you could get 0, you could get what was there previously, or 42. There is no "normal" behaviour at that point by definition.

Alexander Kondratskiy
  • 4,156
  • 2
  • 30
  • 51