在函数外访问堆栈对象

Accessing stack objects outside a function

如果我有一个函数可以在堆栈上创建一个 STL 对象并将它们添加到堆栈中。例如,假设我在堆栈上创建 std::pair 并将它们添加到在堆上创建的 std::queue 中。现在,如果我将队列传递到函数外部,另一个将队列作为参数的函数是否可以访问 std::pair 对象。

是的,因为当您 "add" 从堆栈中的对象到从堆中的对象时,您会将驻留在堆栈上的信息复制到 "heap"。

当您 push 对象(在您的情况下为 std::pair)在 std::queue 中时,它会从本地范围复制到 queue。因此,当本地对象超出范围并被删除时,它在 queue 中的副本仍然有效,直到队列本身被删除。

附带说明,emplace 优于 push,因为它将在 queue 中构建 std::pair 而不是复制。

取决于您未提及的几个因素。

首先要检查的是您是将对象复制到队列中,还是将指向对象的指针复制到队列中。以下是每个示例。

std::queue<A> copyQueue;
std::queue<A*> pointerQueue;

void addCopy(A a) {
  copyQueue.add(a);
}

void addPointer(A a) {
  pointerQueue.add(&a);
}

如果它正在存储对象的副本,那么任何有权访问队列的对象都可以毫无问题地访问该对象。如果它存储指针,则取决于该堆栈帧是否已被回收。如果堆栈框架未被触及,则访问该内存将没问题。否则,该值将是垃圾。

法律示例: 函数 A 将指向堆栈分配对象的指针添加到 std::queue Q,然后将 Q 传递给函数 B。由于函数 A 尚未返回,函数 B 可以毫无问题地访问 Q 中的对象。

垃圾示例: 函数 A 将指向堆栈分配对象的指针添加到 std::queue Q,然后 returns Q 到其调用函数 B。由于函数 A 已返回,如果函数 B 尝试访问 Q.

中的对象,它将收到垃圾