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

Reallocation of Automatic Variables in a Worker Thread

本文关键字:新分配 分配 线程 变量 工作      更新时间:2023-10-16

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

如果这个代码片段被放置在一个工作线程中,堆栈是否会被保存以便在线程完成时间分配后重新进入,也就是说,xy 是否永远不会被释放?

while (1)
{
    int x = 0;
    int *y = &x;
    while (x < 10)
    {
        int z = 0;
        ++x;
    }
}

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

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

最终导致堆栈溢出?

。自动变量在超出作用域时被清除。如果你愿意,你可以认为堆栈在每次迭代开始时增长,然后在每次迭代结束时缩小。(实际上是否发生这样的事情是另一回事……)

如果这个代码片段被放置在工作线程中,在线程完成时间分配后,堆栈是否会被保存以便重新进入,也就是说,x和y是否永远不会被释放?

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

x, yz的空间将在每次循环中重用。这里没有动态的分配和回收。

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

对于这种情况,您可以通过使用

轻松检查编译器正在做什么。

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>