Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is local pointer stored in memory?

Tags:

c

pointers

I am beginner in C. I have one program as below:

int main()
{
    char* func();
    char *c;
    c = func();
    printf("%s", c);
}

char* func()
{
    char *ptr = "OK";
    return ptr;
}

As we all know, ptr is a local variable of func() and is a pointer. The scope is local. But when ptr is returned to the caller, main, it is still valid and when c is printed, it prints "OK".

How is this possible? In which memory segment is ptr stored; stack, or heap?

like image 485
ravi ravi Avatar asked Jul 14 '12 04:07

ravi ravi


4 Answers

This is what's going under the hood when using pointer (Note that pointer is just like what the name implies, something like a finger pointing to something).

Let's break down your codes and understand it bit by bit. In your main function, you declared a character pointer *c

char *c;

Then you did this:

c = func();

which tells the c pointer to point to whatever this func() is pointing to.

Let's look at your function

char* func()
{
    char *ptr = "OK";
    return ptr;
}

The first line, again, declare a character pointer ptr, and assigned "OK" to that address (Note: pointer just points to some memory address). So now, that address contains the string "OK" (or more precisely, an array of char).

Then you return ptr, which is the address of where "OK" is located at. Note that because ptr is declared in func(), it is a local variable. Hence, once return, it is removed from the stack (poof! Gone).

However, because in your main():

c = func(); 

The variable c is pointing to the address of where "OK" is stored. Hence, even though the variable ptr no longer exist, the variable c knows where it is, and can still access "OK".

To answer your question:

  • ptr is stored at stack
  • and ptr is pop off from the stack when you exit the func()
like image 61
Arial Avatar answered Oct 23 '22 12:10

Arial


Let us forget about stack/heap for a moment. Let's talk C.

The local variable ptr doesn't exist outside func, so the caller cannot and should not refer to it.

But C doesn't do pass by reference. Everything is passed by value. func returns the value stored in ptr to its caller. Much like you would return the value of an int or any other type.

So for your example, ptr's value is the address of a string literal called "OK". And string literals are valid during the entire scope of the program. So func returns the address of a string literal, which is allowed to be dereferenced anywhere in the program.

To be more clear, func is equivalent to:

const char * func (void)
{
  return "OK";
}

This is why everything works out fine.

It is also useful to know that while the following is OK:

const char * func (void)
{
  char *ptr = "OK";
  return ptr;
}

This is not:

const char * func (void)
{
  char ptr[] = "OK";
  return ptr;
}

It is not OK because now you're returning a pointer to an array which is local to func.

One more small point. It should be: const char * func (), because "OK" is not allowed to be modified.

like image 27
ArjunShankar Avatar answered Oct 23 '22 13:10

ArjunShankar


When you're calling the function, all its local variables and return address pushes onto the stack. So ptr will be on the stack, but "OK"-string in constant data section. When you're returning from func, value of ptr is assigned to c variable, ptr is no longer exists (actually, exists), but its value stored in c.

like image 3
flamingo Avatar answered Oct 23 '22 13:10

flamingo


The text "OK" is stored in the constant data section of your executable (which is loaded into memory when your process is started). Although ptr is a local variable, the compiler initialises it to point to the "OK" that is stored elsewhere. When you return ptr to the caller, the pointer still points to the same "OK".

like image 2
Greg Hewgill Avatar answered Oct 23 '22 11:10

Greg Hewgill