-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 では、返されたローカル変数アドレスの内容は機能しますが、関数 localStrPtr では、正しい値はmalloc で「のみ」返されますが、ローカル char str[20] では返されません。str[20] で機能しないのはなぜですか?

  2. COMPILE LOG に、3 つの関数すべてについて以下の行が表示されるのはなぜですか?

    • stringManip.c:27: 警告: 関数はローカル変数のアドレスを返します
    • stringManip.c:34: 警告: 関数はローカル変数のアドレスを返します
    • stringManip.c:41: 警告: 関数はローカル変数のアドレスを返します
4

1 に答える 1

2

3 つのケースすべてで未定義の動作。その「未定義」には、それが機能する可能性が含まれています。または、機能しているように見えます。時々。

スタックに割り当てられているローカル変数へのポインターを返しています。その変数がスコープ外になると、そのメモリはその変数用に予約されなくなります。これは、関数が戻るときです。内容が変更されるかどうか、またいつ変更されるかは運次第です。あなたのケースで起こるように、いくつかのケースでは幸運でしたが、他のケースでは幸運ではありませんでした。別の日に、コンパイラーが内部で別の選択を行った可能性があり、動作が異なります。または、(おそらく) 次にくしゃみをしたときにそのデータが上書きされるかもしれません。

やらないでください。

于 2013-01-08T23:59:15.463 に答える