c++ - 在函数中填充容器避免段错误

标签 c++ stl scope segmentation-fault

我来自 Java,在那里填充容器不需要思考。我现在使用 C++ 的问题是,用在函数范围内声明的数据填充函数中的容器会导致错误,当我想访问它时数据不再存在。 我找不到解决这个问题的教程,所以我采用了 Java 方式,只让容器获得用“new”声明的指针。但是现在我被迫返回一个

std::list<Vertex<float> >

从一个函数开始,我认为这可能是学习如何填充和返回这样一个东西的好时机。这会不会

{
std::list<Vertex<float> > myList;
Vertex<float> v(0.0, 0.1, 0.2);
myList.push_back(v);
myList.push_back(Vertex<float>(1,0, 1.1, 1.2));
return myList;
}

作为示例函数体真的可以吗?如果是,为什么 v 仍然存在于范围之外?容器中的每次插入是否也意味着复制?

最佳答案

这会“很好”地工作,因为那里的每个操作都会创建一个拷贝。

  • myList.push_back(v); 创建了 v 的拷贝,这样 v 的可见性现在就无关紧要了。
  • return myList; 将列表的拷贝返回给调用函数,因此 myList 的可见性现在无关紧要。调用函数应该复制此列表以将其保留在范围内,否则它将在调用此函数的行执行结束时被销毁。

之所以引用 fine 是因为拷贝通常很贵。在您的情况下,它们非常小,因此可能无关紧要,并且在许多情况下,它们可能会被优化掉,但仍然需要牢记这一点。

旧的 C++ 优化方式是通过引用传递列表并使用它来构造您的列表,而不是通过值返回。

void MakeMeAList(std::list<Vertex<float> >& aList){
    ....
}

std::list<Vertex<float> > aList;
MakeMeAList(aList);

正如@billz 所暗示的那样,Return Value Optimization即使没有这样做,也应该优化掉拷贝。

新 C++ (c++11) -
使用 emplace_back 来构造列表,只要不再使用输入变量,就会比复制更有效。 (感谢@Troy)

我的 C++11 很弱,我几乎可以肯定即使按值返回也是可以的,因为 Move 语义会优化它,但我只有 95% 的把握。

关于c++ - 在函数中填充容器避免段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14311637/

相关文章:

loops - ColdFusion 中是否存在 "loop"范围?

c++ - 为什么 std::string 分配两次?

c++ - 使用 boost::bind 迭代 std::map

c++ - std::string::operator[] 的结果地址是否指向一个可写的、以 nul 结尾的缓冲区?

javascript - AngularJS 从 $http.get 函数访问范围

javascript - 使用闭包而不是原型(prototype)有缺点吗?

c++ - 二元运算符和重载、加法等

c++ - 我第二次使用 Cin.get() 时不工作

c++ - QTextStream 行为搜索不符合预期的字符串

c++ - 如何将 "<<"与我自己的结构一起使用?