工作线程中自动变量的重新分配
Reallocation of Automatic Variables in a Worker Thread
我是否认为,在下面的代码片段中,自动变量x
和y
将在每次while循环传递时在堆栈上重新分配并且永远不会释放,最终导致堆栈溢出?在从内部while
循环的范围激发后释放之前,每次通过是否也会有10次z
的重新分配?
如果这个代码片段被放置在一个工作线程中,堆栈是否会被保存以便在线程完成时间分配后重新进入,也就是说,x
和y
是否永远不会被释放?
while (1)
{
int x = 0;
int *y = &x;
while (x < 10)
{
int z = 0;
++x;
}
}
不,没有问题。自动变量每次都可以很容易地重用相同的空间。请记住,自动变量的生命周期在代码块结束时结束,因此它们的生命周期不会超过一次迭代。
(实际上,您需要大量的更多的代码来构建每次迭代使用不同的内存位置的东西——您必须在周围保留一个额外的计数器并每次计算偏移量!)
最终导致堆栈溢出?
。自动变量在超出作用域时被清除。如果你愿意,你可以认为堆栈在每次迭代开始时增长,然后在每次迭代结束时缩小。(实际上是否发生这样的事情是另一回事……)
如果这个代码片段被放置在工作线程中,在线程完成时间分配后,堆栈是否会被保存以便重新进入,也就是说,x和y是否永远不会被释放?
在一个正常运行的系统中,每个线程都有自己的堆栈,当该线程终止时,该堆栈将被清理。
x
, y
和z
的空间将在每次循环中重用。这里没有动态的分配和回收。
通常,局部自动变量的空间在函数入口时在堆栈上分配,并在函数结束时释放。
对于这种情况,您可以通过使用
轻松检查编译器正在做什么。 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>
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 如何增加以前由新运算符分配的 C++ std::list 数组的大小?
- 为模板参数类型中的新对象分配内存
- 新运算符分配的大小大于声明的大小.为什么
- 在C++中分配分配
- 为什么支撑初始化分配分配填充垃圾变量
- C 新操作员分配新内存
- 新不分配内存?
- 如果我的C++“新”内存分配失败,如何找出返回值
- 我可以用新的分配内存块吗?
- COM / DCOM:服务器存根不会为现有接口中的新方法分配内存
- 在线程在 C++ 中完成后将新任务分配给线程
- 只能使用CUDA中的新运算符分配有限的内存
- 与将新内容分配给向量的指针斗争
- 确定C++中新运算符分配的内存大小
- 按新内存分配
- 是否有必要使用 'new' 将新指针分配给与指向同一结构的先前存在的指针相同的结构?如果是这样,为什么?
- 用于新运算符分配的公共内存
- boost::io_service post方法是否引起新的分配?
- 如何在C++中检索由新运算符分配的对象的地址