2

我知道编译器优化有时会导致堆栈帧波动。所以我的问题是,在 c++ 中创建堆栈指针并将其传递给另一个函数并期望它指向被调用者中的同一个对象是否总是安全的。由于编译器优化,是否有可能最终指向一个意外的位置。

例如,对于任何编译器,这总是安全的吗?

int main(){
   std::ofstream f("somefile");
   foo(&f);
   return 0;
}

或者我应该使用堆来获得一致的结果。

int main(){
   std::ofstream *f=new std::ofstream("somefile");  
   foo(f);
   close(*f);
   delete f;
   return 0;
}
4

2 回答 2

5

当存在指向生命周期已结束的对象的指针时,将创建悬空指针:

std::string* s;
{
    std::string s1("hello");
    s = &s1;
}
// 's' now a dangling pointer because 's1' has been destructed.

这种情况在任何一个发布的代码片段中都不存在,因此两者都是安全的。(尽管第一个更好,因为它避免了不必要的动态内存分配)。

于 2013-05-19T09:05:25.150 回答
2

在块中定义的对象的生命周期延伸到块的末尾,这取决于在对象定义和块的末尾之间调用了哪些函数。因此,您的第一个示例没有问题。

您可能对相反的方法感到困惑:返回指向函数本地对象的指针是不安全的

std::ofstream * foo() {
  std::ofstream f("somefile");
  return &f;
}

int main() {
  std::ofstream * f = foo();
  // At this point there's no guarantee that f points to a valid object
}
于 2013-05-19T09:40:19.500 回答