0

In the program below, the function getcc() returns pointer to a char array that was allocated inside getcc(). When I pass that pointer in printf with %s format specifier, it does not print anything.

#include<stdio.h>
char* getcc();

int main(){
  char *cp = getcc();
  printf("%s",cp);
}

char* getcc(){
  char c_arr[] = "cow";
  return c_arr;
}

However, when the char array is made into an external variable, it works as expected and prints the word cow.

#include<stdio.h>
char* getcc();

int main(){
  char *cp = getcc();
  printf("%s",cp);
}
char c_arr[] = "cow";
char* getcc(){
  return c_arr;
}

Output

cow

Also, if I try to print the individual chars with "%c" format specifier, it is working as expected.

#include<stdio.h>
char* getcc();

int main(){
  char *cp = getcc();
  printf("%c%c%c",*cp,*++cp,*++cp);
}

char* getcc(){
  char c_arr[] = "cow";
  return c_arr;
}

Output

cow

What is the reason behind this phenomenon?

4
  • 4
    Can a local variable's memory be accessed outside its scope?. In the first example, the memory for c_arr is freed when getcc() returns, and you are now operating with a pointer to freed memory. Commented Jul 10 at 3:59
  • Why is it not working with "%s", but working with "%c"?
    – Cryogen
    Commented Jul 10 at 4:08
  • Does printf somehow detects the memory is freed when "%s" is passed to it?
    – Cryogen
    Commented Jul 10 at 4:21
  • This seems to be compiler specific – e.g. in godbolt.org/z/54czPdM1a gcc protects the user by returning a null pointer instead of the actual address of the value on stack, but if you switch to e.g. (some versions of) clang, they return the real value (and the program crashes).
    – AKX
    Commented Jul 10 at 5:50

1 Answer 1

0

Automatic variables (c_arr in this case) are stored on the stack. Once the function (getcc()) returns, those variables just go out of your jurisdiction because the stack shrinks (the stack pointer is increased). One should not be relying on data which is beyond the stack pointer. One way other than having an external variable is to allocate space for the array using malloc() within getcc() and then return that address. This works because malloc() will reserve space on the heap.

Trying to dereference an address of an automatic variable which belongs to a function which has returned is technically undefined behaviour and there is not much one would gain by trying to reason why it does or does not work.

Not the answer you're looking for? Browse other questions tagged or ask your own question.