2017-11-16 3 views
2
for(int i=0; i<10;i++){ 
    int j = i; 
    cout << &j << endl; 
} 

これは、各繰り返しで同じアドレスjを出力します。私はCでも同じ動作をしていることに気付きました。それは異なる繰り返しのために異なるアドレスでなければなりませんか?異なるアドレスが印刷され
Pythonで、私のシステム上のC++ -v Javaでループ内で定義された変数のアドレスが各繰り返しで変更されないのはなぜですか?

for i in range(10): 
    j = i 
    print(hex(id(j))) 

それを確認できませんでしたローカル変数のアドレスは、の実装の詳細である。この

Using built-in specs. 
COLLECT_GCC=c++ 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper 
OFFLOAD_TARGET_NAMES=nvptx-none 
OFFLOAD_TARGET_DEFAULT=1 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.2.0-8ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3) 
+0

実行中のコンパイラの最適化は何ですか? – Grantly

+3

なぜ別のアドレスにする必要がありますか?コンパイラは同じアドレスを自由に再利用できます。 – AndyG

+5

あなたはPythonで変数のアドレスを取っていません。 Pythonはこれを行う方法を提供していません。 – user2357112

答えて

8

を返します。コンパイラ。

ローカルがこのようなスコープになると、コンパイラは以前と同じアドレスを再利用するか、そうでない可能性があります。どちらにも依存してはいけません。

実際には、最適化をオフにすると、コンパイラが毎回同じアドレスを使用する方が簡単です。実際、関数aが関数bを複数回呼び出す場合、関数bのローカル変数は、関数が呼び出されるたびに同じ場所にある可能性が非常に高いです。

これはやはり実装の詳細です。これは、異なるコンパイラー間で、または異なる最適化設定を使用する同じコンパイラーでは保証されません。

+2

ローカルは、他のすべての変数とは異なるアドレスを持つことが保証されているので、このようなスコープに入るローカルだけではありません。これはもはや存在しなくなった以前のループ反復からの変数に関するものです。 – hvd

+0

@hvd:それは正しいです、存在はここの重要な概念でありスコープではありません。人々はこれを議論するための正しい用語を持っています:**スコープ**は**です** **オブジェクトの**名前**は見えます。 **生涯**は** **オブジェクト**が存在する場合**です。スコープはコンパイル時にのみ存在します。寿命は実行中にのみ存在します。 –

0

繰り返しごとに異なるアドレスにしないでください。

このようにする必要はありません。実際、ローカル変数が関数呼び出しフレーム(所謂コールスタック上)に置かれている共通の実装では、アドレスが不変であることはむしろ簡単です。これは、フレームの開始位置と同じ空間を再利用するだけです。 Pythonでの実装が異なるため

Pythonで異なるアドレスが

印刷されています。各繰り返しにおいて、iは、異なるオブジェクトを参照しています。これは、異なるオブジェクトと値をとる同じストレージではありません。

0

アドレスは実装定義です。しかし、変数は、オブジェクトがを解体する必要があるため、を逆順にしてを構築するため、スタック状のメモリ構造上に作成されます。

ヒープ(またはフリーストア)からランダムなメモリを割り当てるのではなく、ループのたびにスタックメモリ構造の同じ部分を再利用する可能性があります。

これについて考えると、各ループの始めに変数が作成され、ループの終わりに破棄されて、ただ占有していたメモリが解放されます。次回のループ開始時に同じ場所にオブジェクトを再作成するのは驚くべきことではありません。

関連する問題