1

我是否正确地认为,在下面的代码片段中,自动变量xy将在 while 循环的每次传递中重新分配到堆栈上并且永远不会释放,最终导致堆栈溢出?z在从内while循环范围激发后释放之前,是否还会在每次传递中重新分配 10次?

如果这个片段被放置在一个工作线程中,堆栈是否会在线程完成其时间分配后被保存以供重新进入,即,将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

不,没有问题。自动变量每次都可以轻松地重用相同的空间。请记住,自动变量的生命周期在块的末尾结束,因此它们的生命周期永远不会超过一次迭代。

(事实上​​,你需要更多的代码来构建每次迭代使用不同内存位置的东西——你必须保留一个额外的计数器并每次计算一个偏移量!)

于 2013-01-15T23:34:20.573 回答
1

x的空间将在每个循环中重复使用。任何地方都没有动态分配或释放。yz

通常局部自动变量的空间会在函数入口处分配到栈上,并在函数结束时释放。

于 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 回答