利用vector的元素存储在堆中的事实
Exploiting fact that elements of vector are stored in heap?
假设你有这样的内容
#include <iostream>
#include <vector>
using namespace std;
vector<int> test()
{
vector <int> x(1000);
for (int i = 0; i < 1000; i++)
{
x[i] = 12345;
}
return x;
}
int main(int argc, const char * argv[])
{
vector<int> a = test();
return 0;
}
,其中在函数中创建一个矢量并填充一些元素(在本例中,我选择了12345,但它们不一定都是相同的)。
我读到向量的元素存储在堆上,而引用和头数据存储在堆栈上。在上面的代码中,当返回x
时,必须调用复制构造函数,这将花费O(n)时间将所有元素复制到一个新向量中。
然而,是否有可能利用堆上已经存在的所有元素的事实,只返回指向这些元素的指针之类的东西,然后只创建一个使用该指针指向这些完全相同的元素的向量,从而避免需要复制vector的所有元素?
编译器会为您完成这些工作,让您可以腾出时间编写漂亮、易于阅读的代码,而不是为了优化而乱写代码。
当你为函数返回一个值时,允许编译器省略返回值对象。最终结果是编译器可以在a
的实际内存位置创建x
。
即使它不这样做(例如,由于某种原因它选择不这样做,或者你通过编译器开关禁用它),那么仍然有移动的可能性。
当发生移动时,向量将指针的所有权从x
转移到返回值,然后从返回值转移到a
。这使得x
等成为空向量,然后正确地销毁。
你可以通过编写一个测试类(而不是vector<int>
)来探索这个问题,它为它的默认构造函数、复制构造函数和移动构造函数输出一些东西,例如
#include <iostream>
struct A
{
A() { std::cout << "defaultn"; }
A(A const &) { std::cout << "copyn"; }
A(A &&) { std::cout << "moven"; }
};
A func() { A a; return a; }
int main()
{
A b (func());
}
使用g++输出:
default
使用g++ -fno-elide-constructors输出:
default
move
move
相关文章:
- 将字符串存储在c++中的稳定内存中
- 伪造事实↔false
- std::原子加载和存储都需要吗
- C++:将控制台输出存储在宏中更好吗
- 使用QProcess执行命令,并将结果存储在QStringList中
- 访问存储在向量C++中的结构的多态成员
- 如何从存储在std::映射中的std::集中删除元素
- 存储模板类型以强制转换回派生<T>
- 类型总是使用其大小存储在内存中吗
- 当字符串存储在变量中时,如何将字符串转换为wchar_t
- 使用无符号字符数组有效存储内存
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 带结构的二维矢量:如何存储元素
- 添加存储在向量中的大整数的函数出现问题
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 在std::vector上存储带有模板的类实例
- 谷歌测试中的期望值存储在哪里
- 为什么C中的通用链表中存储的数据已损坏
- 利用vector的元素存储在堆中的事实