1

次のスニペットでは、自動変数xyが while ループのすべてのパスでスタック上で再割り当てされ、解放されることはなく、最終的にスタック オーバーフローにつながると考えるのは正しいでしょうか? 内部ループzのスコープから励起された後に解放される前に、各パスでの再割り当ても 10 回行われますか?while

このスニペットがワーカー スレッドに配置された場合、スレッドが時間割り当てを実行した後、再エントリのためにスタックが保存されますか。つまり、割り当てが解除されることはxありy ませんか?

while (1)
{
    int x = 0;
    int *y = &x;

    while (x < 10)
    {
        int z = 0;
        ++x;
    }
}
4

4 に答える 4

1

最終的にスタックオーバーフローにつながる?

いいえ。自動変数は、スコープ外になるとクリーンアップされます。必要に応じて、各反復の開始時にスタックが成長し、各反復の終了時に縮小すると考えることができます。(実際にそうなるかどうかは別問題ですが…)

このスニペットがワーカー スレッドに配置された場合、スレッドが時間割り当てを実行した後、再エントリのためにスタックが保存されますか。つまり、x と y の割り当てが解除されることはありませんか?

機能しているシステムでは、各スレッドは独自のスタックを取得し、そのスレッドが終了するとクリーンアップされます。

于 2013-01-15T23:34:08.677 に答える
1

いいえ、問題ありません。自動変数は、毎回同じスペースを簡単に再利用できます。自動変数の有効期間はブロックの最後で終了するため、1 回の反復よりも長く存続することはありません。

(実際、各反復で異なるメモリ位置を使用するものを構築するには、さらに多くのコードが必要になります。余分なカウンターを保持し、毎回オフセットを計算する必要があります!)

于 2013-01-15T23:34:20.573 に答える
1

xyおよびのスペースは、zすべてのループ ラウンドで再利用されます。動的な割り当てや割り当て解除はどこにもありません。

通常、ローカル自動変数用のスペースは、関数の入り口でスタックに割り当てられ、関数の終了時に解放されます。

于 2013-01-15T23:35:17.287 に答える
1

このような状況では、次を使用してコンパイラが何をしているかを簡単に確認できます。

gcc -g -c yourfile.c

次に、生成されたアセンブリを

objdump -d -M intel -S yourfile.o:

00000000 <main>:
int main() {
   0:   55                      push   ebp
   1:   89 e5                   mov    ebp,esp
   3:   83 ec 10                sub    esp,0x10

ああ!ここで、スタック ポインターが変更されます。関数の残りの部分はそのままにしておくことに注意してください。スタックは成長しません。

    while (1)
        {
            int x = 0;
   6:   c7 45 f4 00 00 00 00    mov    DWORD PTR [ebp-0xc],0x0

入れましょx[ebp-0xc]...

            int *y = &x;
   d:   8d 45 f4                lea    eax,[ebp-0xc]
  10:   89 45 f8                mov    DWORD PTR [ebp-0x8],eax

...そしてy[ebp-0x8]

            while (x < 10)
  13:   eb 10                   jmp    25 <main+0x25>
        {
                int z = 0;
  15:   c7 45 fc 00 00 00 00    mov    DWORD PTR [ebp-0x4],0x0

zは常に[ebp-0x4]!

                ++x;
  1c:   8b 45 f4                mov    eax,DWORD PTR [ebp-0xc]
  1f:   83 c0 01                add    eax,0x1
  22:   89 45 f4                mov    DWORD PTR [ebp-0xc],eax
  25:   8b 45 f4                mov    eax,DWORD PTR [ebp-0xc]

xまだ[ebp-0xc]

  28:   83 f8 09                cmp    eax,0x9
  2b:   7e e8                   jle    15 <main+0x15>
  2d:   eb d7                   jmp    6 <main+0x6>
于 2013-01-16T00:00:23.317 に答える