Difference between - returning a 'local' c

2020-05-09 23:18发布

问题:

This question already has answers here:
Closed 7 years ago.

Possible Duplicate:
Can a local variable’s memory be accessed outside its scope?

Here is a simple code, where in 3 different functions [ localStrPtr, localIntPtr, localCharPtr] return a pointer to their local variables [string, integer, char] in their respective functions.

CODE:

#include <stdio.h>

char*  localStrPtr (char*);
int*   localIntPtr (int, int);
char*  localCharPtr (char);

main()
{
    int *pInt;
    char *pChar;

    printf( "localStrPtr = %s\n", localStrPtr("abcd") );

    pInt = (int*) localIntPtr(3, 5);
    printf( "localIntPtr = %d\n", *pInt );

    pChar = (char*) localCharPtr('y');
    printf( "localCharPtr = %c\n", *pChar );
}

char* localStrPtr(char* argu)
{
    char str[20];
    // char* str = (char*) malloc (20);

    strcpy (str, argu);
    return str;
}

int* localIntPtr (int argu1, int argu2)
{
    int local;
    local = argu1 + argu2;
    return (&local);
}

char* localCharPtr (char argu)
{
    char local;
    local = argu;
    return (&local);
}

COMPILE LOG:

stringManip.c: In function `localStrPtr':
stringManip.c:27: warning: function returns address of local variable
stringManip.c: In function `localIntPtr':
stringManip.c:34: warning: function returns address of local variable
stringManip.c: In function `localCharPtr':
stringManip.c:41: warning: function returns address of local variable

RUN LOG:

localStrPtr =
localIntPtr = 8
localCharPtr = y

As you can see in the log file, localStrPtr returns "some garbage", whereas localIntPtr and localCharPtr return "expected" values.

But, in the function localStrPtr, if I change [ "char str[20]" -to-> "char* str = (char*) malloc (20)" ], localStrPtr returns the string "abcd" correctly. Here is the RUN LOG, once the above change is made.

NEW RUN LOG:

localStrPtr = abcd
localIntPtr = 8
localCharPtr = y

QUESTIONS:

  1. In functions localIntPtr and localCharPtr, contents of the returned local variable addresses WORKED, but for the function localStrPtr, correct value is returned "only" with malloc, but will not with local char str[20]. Why doesn't it work with str[20] ?

  2. Why do we see in the COMPILE LOG, the lines below for all the 3 functions ?

    • stringManip.c:27: warning: function returns address of local variable
    • stringManip.c:34: warning: function returns address of local variable
    • stringManip.c:41: warning: function returns address of local variable

回答1:

Undefined behaviour, in all 3 cases. That 'undefined' includes the possibility that it might work. Or look like it's working. Sometimes.

You're returning a pointer to a local variable, which is allocated on the stack. That memory is no longer reserved for that variable when it goes out of scope, which will be when the function returns. Whether or not the contents get altered, and when that happens, is down to luck. As it happens in your case, you got lucky with a couple of cases, but not the other. On a different day, the compiler might have made some different choice internally, and it behaves differently. Or maybe (probably) that data gets overwritten the next time you sneeze.

Don't do it.