1

次のコードで2つの関数を記述しました。どちらも同じ出力を生成することを目的としています。しかし、g()ループを持つ関数は、以下に示すように、私が期待していたものとは異なる出力を生成します。

#include <stdio.h>

struct S { int i; };

void f(void)
{
    struct S *p;

    int i = 0;

    p = &((struct S) {i});
    printf("%p\n", p);

    i++;

    p = &((struct S) {i});
    printf("%p\n", p);
}

void g(void)
{
    struct S *p;

    for (int i = 0; i < 2; i++)
    {
        p = &((struct S) {i});
        printf("%p\n", p);
    }
}

int main()
{   
    printf("Calling function f()\n");
    f();

    printf("\nCalling function g()\n");
    g();
}

出力:

Calling function f()
0023ff20
0023ff24

Calling function g()
0023ff24
0023ff24

呼び出されたときのアドレスpが同じになるのはなぜですか?g()

4

2 に答える 2

5

さて、あなたが何を達成しようとしているのか正確にはわかりませんが、ここで何が起こるかは次のとおりです。

  • C99の(struct S){i}表記は、スタック上に新しいデータ構造を作成します
  • このデータ構造は、作成されたスコープの最後で自動的に破棄されます

したがって、f()関数では、実際には関数全体のスコープ内に2つの異なる構造を作成します(同じポインターにアドレスを割り当てた場合でも)。したがって、2つの異なるアドレスになります。

void f(void)
{
    struct S *p;

    int i = 0;

    p = &((struct S) {i}); // <- first data structure, let's call it A
    printf("%p\n", p);     // <- address of the structure A printed

    i++;

    p = &((struct S) {i}); // <- second data structure, let's call it B
    printf("%p\n", p);     // <- address of the structure B printed
}                          // <- both A and B destroyed

しかし、g()機能上、pはブロックの内側のブロックで作成および破棄されるforため、pがスタックの同じ位置に何度も割り当てられ、常に同じアドレスが与えられます。

void g(void)
{
    struct S *p;

    for (int i = 0; i < 2; i++)
    {
        p = &((struct S) {i}); // <- data structure A created
        printf("%p\n", p);     // <- data structure A's address printed
    }                          // <- data structure A destroyed
}
于 2012-12-13T17:48:18.907 に答える
2

アセンブリコードを確認する必要がpありますが、自動割り当て変数(スタックに割り当てられている)のアドレスを使用してループスコープでローカルに割り当てられているため、スタック上の同じスペースを再利用するだけだと思います。

コンパイラでは、最初の反復の終わりにを使用できないことが確実であるのf()に対し、両方の構造体が同じスコープ内に共存するため、これは実行されません。g()&((struct S) {0})

-O2何かが変わるかどうかを確認するために、gcc4.2で好奇心を試してみました。

Calling function f()
0x7fff5fbff388
0x7fff5fbff380

Calling function g()
0x7fff5fbff390
0x7fff5fbff390
于 2012-12-13T17:31:55.610 に答える