2

重複の可能性:
ローカル変数のメモリにそのスコープ外でアクセスできますか?
ローカル変数の戻りアドレス

質問があります。まずコードを見てください

    #include <stdio.h>

int sum();          /* function declaration */

int main()
{
    int *p2;
    p2 = sum();         /* Calling function sum and coping its return type to pointer variable p2  */
    printf("%d",*p2);
} /*  END of main  */ `

int sum()           
{
    int a = 10;
    int *p = &a;
    return p;
} /*  END of sum */

答えは10で変数aのアドレスだと思いますが、私のtesacherは、aは関数に対してローカルなので、関数が戻るか実行が終了すると、その値はメモリの場所から削除されると言います。私はこのコードを試してみましたが、答えはもちろん 10 と a のアドレスです。私は GNU/GCC コンパイラを使用しています。何が正しくて何が間違っているかは誰にも言えません。前もって感謝します。

4

5 に答える 5

3

int*あなたの先生は絶対に正しいです:の代わりに戻るようにプログラムを修正しても、intプログラムにはまだ未定義の動作が含まれています。問題は、以前に配置されていたメモリが、戻ったaときに再利用できるようになっていることです。sumメモリはアクセスできるように手付かずのまま残っている可能性があるため、10 個を出力することさえできますが、この動作はまだ定義されていません。あるプラットフォームで実行され、他の 10 個のプラットフォームでクラッシュする可能性があります。

于 2012-08-18T01:18:43.947 に答える
2

正しい結果が得られるかもしれませんが、それは運が良かったからです。sum() が返されるまでに、 aのメモリがシステムに返され、他の変数で使用できるため、値はかわった。

例えば:

#include <stdio.h>

int* sum();          /* function declaration */
int* sum2();          /* function declaration */

int main()
{
    int *p2;
    p2 = sum();         /* Calling function sum and coping its return type to pointer variable p2  */
    sum2();
    printf("%d",*p2);
}

int* sum()           
{
    int a = 10;
    int *p = &a;
    return p;
} /*  END of sum */

int* sum2()           
{
    int a = 100;
    int *p = &a;
    return p;
} /*  END of sum */

このコードでは、aが sum2() によって再利用されるため、メモリ値を 100 でオーバーライドします。

ここでは、int へのポインターを返すだけです。オブジェクトを返すとします。

TestClass* sum()           
{
    TestClass tc;
    TestClass *p = &tc;
    return p;
}

次に、tc を逆参照すると、tc が指すメモリが完全に台無しになる可能性があるため、奇妙なことが起こります。

于 2012-08-18T01:22:25.780 に答える
0

ポインターは、10 が存在するメモリ内の場所をまだ指しています。ただし、C の観点からは、メモリは割り当てられておらず、再利用できる可能性があります。スタックにさらにアイテムを配置したり、メモリを割り当てたりすると、メモリのその部分が再利用される可能性があります。

于 2012-08-18T01:18:50.543 に答える
0

a関数 sumのオブジェクトにはautomatic lifetime. それが宣言されたスコープ (関数本体) がプログラム フロー (return関数の最後のステートメント) によって残されるとすぐに、その有効期間は終了します。

その後、a住んでいたメモリにアクセスすると、期待どおりに実行されるか、ドラゴンが召喚されるか、コンピューターに火がつきます。これはC では未定義の動作と呼ばれます。ただし、C 標準自体には、deleting something from memoryメモリの概念がないため、何も言及されていません。

于 2012-08-18T01:33:08.540 に答える
0

論理的に言えば、いったん終了aすると存在しなくなります。sumその有効期間は関数のスコープに制限されます。 物理的に言えば、a占有されていたメモリはまだそこにあり、値 10 のビット パターンをまだ含んでいますが、そのメモリは別の用途に使用できるようになり、 で使用する前に上書きされる可能性がありますmain。出力が 10 になるか、ガベージになる可能性があります。

変数の有効期間外に変数の値にアクセスしようとすると、未定義の動作が発生します。つまり、コンパイラは状況を自由に処理できます。何かおかしいことをしていることを警告する必要はありません。期待どおりに動作する必要はありません。まったく動作する必要はありません。

于 2012-08-18T12:50:45.990 に答える