工作线程中自动变量的重新分配

时间:2013-01-15 23:32:31

标签: c++ c multithreading memory-management

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

如果此片段放在工作线程中,则在线程服务其时间分配后,是否会保存堆栈以重新进入,即xy 将永远< / em>被解除分配?

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

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

4 个答案:

答案 0 :(得分:1)

  

最终导致堆栈溢出?

没有。当超出范围时,自动变量将被清除。如果你愿意,你可以想到堆栈在每次迭代开始时都在增长,然后在每次迭代结束时收缩。 (在实践中是否发生这种情况是另一回事......)

  

如果此片段放在工作线程中,那么在线程服务其时间分配后是否会保存堆栈以便重新进入,即x和y是否永远不会被释放?

在一个正常运行的系统中,每个线程都有自己的堆栈,当该线程终止时,该堆栈会被清除。

答案 1 :(得分:1)

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

(事实上,你需要很多 more 代码来构造一些东西,其中每次迭代使用不同的内存位置 - 你必须保留一个额外的计数器每次都计算一个偏移量!)

答案 2 :(得分:1)

xyz的空间将在每轮循环中重复使用。任何地方都没有动态分配或解除分配。

通常,本地自动变量的空间将在函数入口处的堆栈上分配,并在函数结束时释放。

答案 3 :(得分: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>