矢量<X*> vec vs 矢量<X>* vec
vector<X*> vec vs vector<X>* vec
两者之间的内存使用量有什么区别:
std::vector<X*> vec
其中每个元素都在堆上,但向量本身不在
和
std::vector<X>* vec
其中向量在堆上声明,但每个元素都是(在堆栈上?
第二个选项没有多大意义 - 这是否意味着矢量指针在堆上,但它指向堆栈上的每个元素?
std::vector<X*> vec
是 X 类的指针数组。例如,在创建不可复制的类/对象数组(如 C++98 中的 std::fstream )时,这很有用。所以
std::vector<std::fstream> vec;
是错误的,并且不起作用。但
std::vector<std::fstream*> vec;
工作,同时您必须为每个元素创建一个新对象,因此例如,如果您想要 5 个 fstream 元素,您必须编写类似的东西
vec.resize(5);
for(unsigned long i = 0; i < vec.size(); i++)
{
vec[i] = new std::fstream;
}
当然,根据您的应用,还有许多其他用途。
现在第二种情况是向量本身的指针。所以:
vector<int>* vec;
只是一个指针! 它不携带任何信息,除非你为向量本身创建对象,否则你不能使用它,比如
vec = new vector<int>();
最终,您可以将其用作:
vec->resize(5);
现在这并不真正有用,因为向量无论如何都会将它们数据存储在堆上并管理它们携带的内存。因此,只有在您有充分理由时才使用它,有时您会需要它。我没有任何关于它如何有用的例子。
如果这是你真正问的:
vector<X>* vec = new vector<X>();
这意味着整个向量及其所有元素都在堆上。这些元素占用堆上的连续内存块。
区别在于您需要在哪里(以及做什么)进行手动内存管理。
每当C++中有一个原始的 C 样式指针时,你需要做一些手动内存管理 - 原始指针可以指向任何东西,编译器不会为你做任何自动构造或破坏。 因此,您需要了解指针指向的位置以及谁"拥有"其余代码中指向的内存。
所以当你有
std::vector<X*> vec;
您无需担心向量本身的内存管理(编译器将为您完成),但您确实需要担心指向X
对象的内存管理,以便您放入向量中的指针。 如果要使用new
分配它们,则需要确保在某些时候手动delete
它们。
当你有
std::vector<X> *vec;
您确实需要担心矢量本身的内存管理,但您不需要担心单个元素的内存管理。
最简单的是,如果您有:
std::vector<X> vec;
然后你根本不需要担心内存管理 - 编译器会为你处理它。
在使用良好的现代C++风格的代码中,以上都不是真的。
std::vector<X*>
是 X
类型对象或其任何子类的句柄集合,您不拥有这些子类。 所有者知道它们是如何分配的,并且会解除它们的分配 - 你不知道也不在乎。
在实践中,std::vector<X>*
只会用作函数参数,该参数表示您不拥有的向量(调用者拥有),但您将对其进行修改。 根据一种常见的方法,它是指针而不是矢量的事实意味着它是可选的。 更罕见的是,它可能被用作类成员,其中已知附加向量的生存期比指向它的类的寿命长。
std::vector<std::unique_ptr<X>>
是各种X
子类(可能直接X
自身)的混合对象的多态集合。 有时,如果移动成本很高X
您可能会非多态地使用它,但现代风格使大多数类型移动起来很便宜。
在 C++11 之前,std::vector<some_smart_pointer<X> >
(是的,右括号之间有一个空格)将用于多态大小写和不可复制大小写。 请注意,some_smart_pointer
不是std::unique_ptr
,当时还不存在,std::auto_ptr
,这在集合中不可用。 boost::unique_ptr
是一个不错的选择。 在 C++11 中,集合元素的可复制性要求放宽为可移动性,因此这个原因完全消失了。(还有一些类型既不可复制也不可移动,例如 ScopeGuard 模式,但无论如何都不应存储在集合中)
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- EASTL矢量<向量<int>>连续的
- Omnet++中的.vec和.sca输出有什么区别?
- vec[i][j] 是否转换为 *(vec + i + j)?
- 如何在编译器C++不智能的情况下实现 GLSL vec* 构造语法?
- 在Rcpp(和RcppArmadillo)中,如何检查vec是否包含复数
- c++14 - vec.begin() 和 begin(vec) 之间有什么区别吗?
- 是否可以使用 std::vector<std::any> vec;这将导致异构数据类型
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 在 opencv 上将 vec 类型转换为标量类型
- OpenCV:当将 std::vector 传递给需要 OutputArray 的函数时,vec 包含垃圾
- C 字符串比较“祝您好运”&gt;“再见”
- 为什么在使用 auto&&it=--vec.end(),是 UB 时自动推导左值引用?
- C++ 犰狳 生成给定 vec 或矩阵的索引 uvec,而不循环它
- 使用高级构造函数将阵列转换为Armadillo Vec
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- 当使用 std::vector::p ush_back 插入未知数量的元素时,是否应该在每次推送时检查 std::vec
- 使用 std::vector,为什么 &vec[0] 未定义的行为,而 vec.data() 是安全的?
- 如何修复此 OpenCV 错误:断言失败((无符号)i < (无符号)cn) 在 cv::Vec<unsigned char,3>:::运算符 (), 文件
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一