c ++将大向量作为输出传递
Posted
技术标签:
【中文标题】c ++将大向量作为输出传递【英文标题】:c++ passing big vectors as output 【发布时间】:2015-11-25 05:45:26 【问题描述】:我有几个大向量(大约有一百万个元素),比如说vector<int> v
在函数或类成员函数中生成。我想在这个函数/成员之外有效地使用这个向量,即当我将它作为输出传递时避免完全复制它
vector<int> make_vect()
vector<int> v(1e6);
... // some analysis
return v;
int main()
vector<int> v = make_vect();
我知道我可以使用指向此向量 vector<int> *v
的指针,但这会使事情变得有点复杂(例如,我必须手动删除它们等等)。我想知道如果我不使用引用或指针,上面的代码会如何表现。
除了复制问题,在上面的代码中,分配的内存是什么时候释放的?除非我调用 v.clear(),否则内容是否永远不会被删除?或者当没有指向容器的变量时它会自动删除它们?
【问题讨论】:
这是 C++11 还是更高版本?尝试和衡量是否有并发症? 将结果向量作为非常量引用参数传递? 您不想使用指针/引用,但要避免复制(通过使用本地向量)。为什么不使用静态/全局的? “手动删除”。我们通常不这样做。拥有std::unique_ptr
和所有。但没关系,当你按值返回时,编译器应该优化复制。
@AmeerJewdaki,那你可能没问题。值返回的东西几乎总是在最坏的情况下被移出,当这种情况发生时,你仍然只有一个占用内存。理想情况下,本地对象的内存将仅用于返回值,但如果不是这样,您仍然不会得到相同向量元素的两个副本。当函数结束时,函数的向量将被销毁,但到那时,返回值已经便宜地窃取了所有内容,而无需到处复制超过几个字节。
【参考方案1】:
这正是您应该返回对象的方式——按值。编译器将应用 NRVO 优化以确保不会发生复制。
【讨论】:
或者即使在没有 RVO 的情况下,对象也将被移动而不是复制(在 C++11 或更高版本中)。 当然,但在当今时代,您将很难让 NRVO 不适用(尽管有调试版本)。 谢谢,我更新了帖子,增加了一个问题,示例代码中分配的内存何时释放? @Blindy,这并不像听起来那么难。例如,返回一个按值参数。 @AmeerJewdaki 当main()
退出时。【参考方案2】:
我喜欢这样做:
void make_vect(vector<int> *dest)
dest->resize(1000000);
... // some analysis
int main()
vector<int> v;
make_vect(&v);
其他人会使用向量&而不是向量*,但我认为使用指针表明被调用的函数应该写入它。
【讨论】:
缺少const
表示写入参数,除非您的意思是调用者必须将&
附加到参数,在这种情况下,有时我确实觉得很遗憾非常量引用是如此透明。
是的,当我看到 make_vect(v) 时,我希望被调用的函数只查看值,无论它是否被复制。 make_vect(&v) 向我表明该函数将写入其中。我承认这可能只是因为我老了。
据我所知,调用站点的额外语法是 Google 样式指南使用指针而不是非常量引用的主要原因。【参考方案3】:
虽然按值传递和使用指针都可以在这种特定情况下工作,但我不会打折使用指针,因为它们有点复杂。如果您正在执行任何动态分配,它实际上可能会简化您现在从指针开始的过程,因此您不必在以后返回并更改所有内容。只是我的两分钱!
【讨论】:
以上是关于c ++将大向量作为输出传递的主要内容,如果未能解决你的问题,请参考以下文章