3
const char *fun1()
{
    const char *a = "hello";
    return a;
}

const char *fun2()
{
    const char a[] = "hello";
    return a;
}

int main(int argc, char *argv[])
{
    printf("%s\n", fun1());
    printf("%s\n", fun2());
    return 0;
}

Output:

cpp:12:12: warning: address of local variable 'a' returned [-Wreturn-local-addr]
   12 |     return a;
      |            ^
passwords.cpp:11:16: note: declared here
   11 |     const char a[] = "hello";
      |                ^
hello
(null)

What's difference between these two method of a assigning a string? I am getting a warning for one while not the other one? I know local variables get destroyed when we return from a function but why this is not the case with fun1()? Does it get memory somewhere else instead of stack?

Ashutosh Aswal
  • 494
  • 3
  • 12

1 Answers1

4

In your case the bytes of the string in fun1() live in static memory. in the other function the bytes are copied from the static memory into a buffer on the stack on initialization. It is undefined to access the returned string that is returned from fun2() because the array on the stack does not exist anymore.

fun1() could be rewritten as

const char fun1()
{
    static const char s[] = "hello";
    const char* a = s;
    return a;
}

fun2() could be rewritten as

const char fun2()
{
    static const char s[] = "hello";
    const char a[6]; // stack allocation (5 letters + 1 zero terminator)
    strcpy(a, s);
    return a; // UB: return pointer to local automatic array
}

So the main reason you get the warning is that the array in fun2() does not exist after the call. You return a pointer into the stack frame, in the same way the following code has the same problem:

struct S { int x, y; };

struct S* fun1()
{
    static struct S s = { 10, 42 };
    return &s; // no problem
}

struct S* fun2()
{
    struct S a = { 10, 42 };
    return &a; // UB
}
cmdLP
  • 1,658
  • 9
  • 19