访问函数外部的堆栈对象

Accessing stack objects outside a function

本文关键字:堆栈 对象 外部 函数 访问      更新时间:2023-10-16

如果我有一个函数在堆栈上创建一个STL对象并将它们添加到堆栈中。例如,我在堆栈上创建std::pair,并将它们添加到堆上创建的std::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);
}

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

法律的例子:函数Astd::queue Q添加一个指向堆栈分配对象的指针,然后将Q传递给函数B。因为函数A还没有返回,函数B可以毫无问题地访问Q中的对象。

垃圾的例子:函数Astd::queue Q添加一个指向堆栈分配对象的指针,然后将Q返回给调用它的函数B。由于函数A已经返回,如果函数B试图访问Q中的对象,它将接收到垃圾。

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

作为旁注,emplace优于push,因为它将在queue中构建std::pair,而不是复制。

是的,因为当你从堆栈中"添加"对象到堆中的对象时,你会将驻留在堆栈中的信息复制到"堆"中。