将变量移动到外部作用域时堆栈会发生什么变化?

What happens to the stack when moving a variable to an outer scope?

我想我了解堆栈的工作原理以及移动变量时会发生什么,但我找不到这个问题的答案。让我解释一下:

当新作用域为entered/created时,在栈顶获取一定量的内存。栈指针指向这块内存。它代表堆栈的当前大小。当范围离开时,通过将堆栈指针 return 指向其先前位置来释放内存。

在 C++11 或更高版本中移动语义,将某些数据的所有权从一个变量移动到另一个变量。这避免了复制数据,因为保存数据的内存保持不变。 move之后,moved-to变量指向数据在内存中的位置,moved-from变量基本上变成了空指针。在这里,我可能会犯第一个错误,将移动语义与指针联系得太紧密。我是吗?

实际问题: 变量在内部作用域中创建,然后移动到外部作用域中的变量。然后内部范围退出。堆栈发生了什么变化?

鉴于上述情况,堆栈指针应该 return 指向它之前的位置并释放内部作用域内存。但它不能这样做,因为来自内部范围的内存仍然有效,因为它现在附加到外部范围变量。外部(可能是全局)范围和以前的内部范围内存之间可能有很多内存 blocked/wasted。一旦外部范围退出,此内存将再次可用。在此之前,筹码量会膨胀。这是真的?这可以避免吗?编译器会阻止这种情况吗?

免责声明、外行术语、狡猾的类比和不可靠的 c++ 知识...

我想我理解你的困惑,

[stack frame a]
std::vector toPopulate;
    [stack frame b]
    std::vector toMove; // will be std::moved into `toPopulate` somehow

当堆栈范围离开 b 并返回到 a 时,move 如何阻止任何复制,因为您显然不能将内存留在堆栈帧中 b...

答:不是! toMove 的堆栈数据被复制到 toPopulatestd::vector 不将数组的内容存储在堆栈中,它仅将 address/pointer 存储到内存中的位置堆。

std::move这里是在告诉vector不要深拷贝自己(不要将堆数据拷贝到堆中的其他地方),只拷贝data 指针,相信我,这样做是安全的,安全是在编译时强制执行的。

所以 toPopulate 被构建,它的 dataCount 和 dataPointer 以及描述 std::vector 可能需要的任何其他东西都 written/copied 到堆内存中,但你的堆数据没有被触及,它也不会被堆栈中的多个 std::vectors 拥有,这确实很麻烦!