0

I was reading this article ( http://www.codeproject.com/Articles/627/A-Beginner-s-Guide-to-Pointers ) which has some code to explain one reason why we should use them. eg. Dynamic Allocation.

Eg.1. The incorrect program:


"This program firstly calls the SomeFunction function, which creates a variable called nNumber and then makes the pPointer point to it. Then, however, is where the problem is. When the function leaves, nNumber is deleted because it is a local variable. Local variables are always deleted when execution leaves the block they were defined in. This means that when SomeFunction returns to main(), the variable is deleted. So pPointer is pointing at where the variable used to be, which no longer belongs to this program."

#include <stdio.h>

int *pPointer;

void SomeFunction()
{
    int nNumber;
    nNumber = 25;    

    // make pPointer point to nNumber:
    pPointer = &nNumber;
}

void main()
{
    SomeFunction(); // make pPointer point to something

    // why does this fail?
    printf("Value of *pPointer: %d\n", *pPointer);
}

Eg.2. The Correct program:


"When SomeFunction is called, it allocates some memory and makes pPointer point to it. This time, when the function returns, the new memory is left intact, so pPointer still points to something useful. That's it for dynamic allocation!"

#include <stdio.h>

int *pPointer;

void SomeFunction()
{
    // make pPointer point to a new integer
    pPointer = new int;
    *pPointer = 25;
}

void main()
{
    SomeFunction(); // make pPointer point to something
    printf("Value of *pPointer: %d\n", *pPointer);
}

My Question:


This above explaination made complete sense to me and I was feeling good about why we use pointers. Then I decided to run the programs to see what happens. I was expecting the first one to display some random number for *pPointer because the 25 had been deleted. Both programs displayed "Value of *pPointer: 25" correctly. Shouldn't the first program have failed as the tutorial said it would?

user2364266
  • 51
  • 1
  • 2
  • possible duplicate of [Returning the address of local or temporary variable](http://stackoverflow.com/questions/2744264/returning-the-address-of-local-or-temporary-variable) – Lstor Jul 02 '13 at 12:39
  • This is a nice explanation: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794 – Lstor Jul 02 '13 at 12:39

6 Answers6

3

It's because it's undefined behavior. You simply are lucky that the printf function haven't written over that location.

The nice thing (if I may be ironic) about undefined behavior, is that it's undefined, you can't really tell what will happen beforehand. Also see nasal demons.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

Both programs displayed "Value of *pPointer: 25" correctly. Shouldn't the first program have failed as the tutorial said it would?

In the first program, nNumber is located on the stack. When SomeFunction() exits, nNumber "goes out of scope," which is to say that it no longer exists from the program's point of view. The memory that was used for that variable is still there, however, and it will contain the same value that it did when nNumber was in scope until some new value is written there. pPointer continues to point to that location, of course, so you can keep looking at the value of that memory. As other functions are executed, that memory will eventually be used for some new variable, and the value will change. The danger is that if you continue to use pPointer expecting it to remain valid, you'll find that the value that it points to keeps changing unexpectedly.

Caleb
  • 124,013
  • 19
  • 183
  • 272
0

That is undefined behaviour. There is no check to ensure that the pointer being de-referenced is pointing to a valid value or not. Check this awesome answer here.

In short,

When the variable goes out of scope, anything is possible at the location where the variable was previously stored (even after you do delete, delete just releases the memory it doesnt necessarily wipe it out).

It might be overwritten already, might be in the process of being over written, or nothing has changed till now. (like in your example). Since, its in a space that is valid to be accessed by your code you don't find any seg-faults etc.

Community
  • 1
  • 1
Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59
0

Local variables are allocated on the stack. When a function exits, the pointer to the top of the stack is modified so that the local variables are off the stack, but the stack is not wiped. Therefore, the value 25 will still be at the memory location pointed to by pPointer. If you call another function with local variables, that memory will be overwritten.

printf() will overwrite the location, but pPointer will be dereferenced for use in an argument before printf() is executed.

user1158559
  • 1,954
  • 1
  • 18
  • 23
0

The reason why the first program worked is because in c++ using a pointer to a destroyed variable is undefined. But what c++ doesn't dictate is what happens to that memory. Local variables are allocated using what is called a Stack Frame in c++ or if you are familiar with Assembly Language "The Stack" after completion of the function often times that memory is not actually destroyed but is rather just not protected from being overwritten. So for a time that pointer may work but at some other point in time the memory that you are pointing too can be overwritten.

The technical explanation for this phenomenon is that when a function is entered its address is pushed onto the stack segment. Local variables are then defined as an offset below this pushed address and the stack pointer. This effectively gives you memory on the stack to access for local variables. But once the function leaves rather than wasting time overwriting that memory the memory is left unprotected for reads and writes from later operations as such the behavior is undefined because we have no idea at what point that memory will no longer be valid and how long that memory is valid is not set in stone and often fluctuates. If you are looking for an explanation this video gives a good overview without going into the hardcore details: http://www.youtube.com/watch?v=vcfQVwtoyHY.

bear
  • 1
0

In the first program, the pointer will still be pointing to the location in memory where the number 25 is stored. This is correct. The problem is not so much that the number 25 has been overwritten; it's that it might have been overwritten. Other programs have free license to mess with that memory location without overstepping bounds with the first program, but until something actually gets around to changing that value, the hardware still stores the number 25.

Panzercrisis
  • 4,590
  • 6
  • 46
  • 85