给定以下函数:
void test(queue<string>* out) {
queue<string> abc = queue<string>();
abc.push("abc");
out = &abc;
}
Run Code Online (Sandbox Code Playgroud)
理论上,abc变量是在堆栈上分配的,并且在函数结束时它必须自动从堆栈中弹出。但我将该变量的引用分配给out作为指针的参数。那么,当调用该函数的上下文传递一个指针来捕获输出时,会发生什么?换句话说,这个手术到底安全吗?
为了把问题说清楚,下面的函数是否与上面的函数等价:
void test(queue<string>* out) {
out->push("abc");
}
Run Code Online (Sandbox Code Playgroud)
第一个功能是安全的,但不等同于第二个。
您只是将一个值分配给out作为局部变量的指针。该局部变量未连接到调用者,并且调用者无法观察到赋值。你的函数没有副作用。它相当于
void test(queue<string>* out) {}
Run Code Online (Sandbox Code Playgroud)
您尚未将abc对象的指针存储在可从函数外部访问的任何位置。
如果这样做了,该指针将在函数调用返回后悬空,因为该abc对象将在此时被销毁。您是否持有指向它的引用/指针根本不重要。在块作用域中声明的变量(不带static或thread_local说明符)具有自动存储持续时间,这意味着它们将始终在声明它们的块末尾被销毁。
取消引用悬空指针将导致程序出现未定义的行为,这意味着您将失去对程序行为的任何保证。
因此,无论是通过返回值还是输出参数,返回指向局部变量的引用或指针都是一个明显的错误。