-1

可能重复:
可以在其范围之外访问局部变量的内存吗?

这是一个简单的代码,其中 3 个不同的函数[localStrPtr, localIntPtr, localCharPtr]在各自的函数中返回一个指向它们的局部变量[string, integer, char]的指针。

代码:

#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);
}

编译日志:

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

运行日志:

localStrPtr =
localIntPtr = 8
localCharPtr = y

正如您在日志文件中看到的,localStrPtr 返回“一些垃圾”,而 localIntPtr 和 localCharPtr 返回“预期”值。

但是,在函数localStrPtr中,如果我更改 [ " char str[20] " -to-> " char* str = (char*) malloc (20) " ],localStrPtr 会正确返回字符串 "abcd"。这是运行日志,一旦进行了上述更改。

新的运行日志:

localStrPtr = abcd
localIntPtr = 8
localCharPtr = y

问题:

  1. 在函数 localIntPtr 和 localCharPtr 中,返回的局部变量地址的内容 WORKED,但对于函数 localStrPtr, “仅”使用 malloc返回正确的值,而不会使用 local char str[20]。为什么它不适用于 str[20] ?

  2. 为什么我们在编译日志中看到所有 3 个函数的以下行?

    • stringManip.c:27:警告:函数返回局部变量的地址
    • stringManip.c:34:警告:函数返回局部变量的地址
    • stringManip.c:41:警告:函数返回局部变量的地址
4

1 回答 1

2

未定义的行为,在所有 3 种情况下。该“未定义”包括它可能起作用的可能性。或者看起来它正在工作。有时。

您正在返回一个指向在堆栈上分配的局部变量的指针。当该变量超出范围时,该内存不再保留给该变量,这将是函数返回时。内容是否被改变,以及何时发生,都取决于运气。正如您的情况一样,您很幸运有几个案例,但不是另一个。在不同的一天,编译器可能在内部做出了一些不同的选择,它的行为也不同。或者也许(可能)下次打喷嚏时数据会被覆盖。

不要这样做。

于 2013-01-08T23:59:15.463 回答