C++ 将对象推回向量内存问题C++;
这里比较初始化对象向量的两种方法C++ 将对象推回向量内存问题C++;,c++,memory,vector,C++,Memory,Vector,这里比较初始化对象向量的两种方法 1. vector<Obj> someVector; Obj new_obj; someVector.push_back(new_obj); 2. vector<Obj*> ptrVector; Obj* objptr = new Obj(); ptrVector.push_back(objptr); 1。 向量someVector; Obj new_Obj; 一些向量。推回(新对象);
1.
vector<Obj> someVector;
Obj new_obj;
someVector.push_back(new_obj);
2.
vector<Obj*> ptrVector;
Obj* objptr = new Obj();
ptrVector.push_back(objptr);
1。
向量someVector;
Obj new_Obj;
一些向量。推回(新对象);
2.
向量向量向量机;
Obj*objptr=新的Obj();
ptrVector.push_back(objptr);
第一个将实际对象而不是对象的指针推回。vector push_back是否复制了正在推送的值?我的问题是,我有巨大的对象和很长的向量,所以我需要找到一个最好的方法来节省内存
- 第二条路更好吗
- 有没有其他方法可以让对象/指针向量在以后找到每个对象并同时使用最少的内存
Obj
类不需要多态行为,那么最好直接将Obj
类型存储在向量中
如果将对象存储在vector
中,则您将承担在不再需要这些对象时手动释放这些对象的责任。在这种情况下,如果可能的话,最好使用vector
,但同样,只有在需要多态行为时才使用
vector
将把Obj
对象存储在堆上(默认情况下,除非覆盖vector
模板中的allocator
)。这些对象将存储在连续内存中,这也可以根据您的用例提供更好的缓存位置
使用向量
的缺点是频繁插入/删除向量
可能会导致重新分配和复制对象。然而,这通常不会成为应用程序中的瓶颈,如果您觉得它是瓶颈,那么您应该对其进行分析
使用C++11,可以大大减少复制的影响。如果您的Obj
类不需要多态行为,那么最好直接将Obj
类型存储在向量中
如果将对象存储在vector
中,则您将承担在不再需要这些对象时手动释放这些对象的责任。在这种情况下,如果可能的话,最好使用vector
,但同样,只有在需要多态行为时才使用
vector
将把Obj
对象存储在堆上(默认情况下,除非覆盖vector
模板中的allocator
)。这些对象将存储在连续内存中,这也可以根据您的用例提供更好的缓存位置
使用向量
的缺点是频繁插入/删除向量
可能会导致重新分配和复制对象。然而,这通常不会成为应用程序中的瓶颈,如果您觉得它是瓶颈,那么您应该对其进行分析
使用C++11,可以大大减少复制的影响。如果可以提前保留大小,则使用向量将占用更少的内存<如果不需要重新分配向量,代码>向量
将必然比向量
使用更多的内存,因为您有指针的开销和动态内存分配的开销。但是,如果您只有几个大对象,则此开销可能相对较小
但是,如果内存即将耗尽,如果无法提前保留正确的大小,则使用vector
可能会导致问题,因为在重新分配向量时,您将暂时需要额外的存储空间
拥有大型对象的大型向量也可能导致内存碎片问题。如果您可以在程序执行的早期创建向量并保留大小,这可能不是问题,但如果稍后创建向量,您可能会由于堆上的内存漏洞而遇到问题。如果您可以提前保留大小,则使用向量将占用更少的内存<如果不需要重新分配向量,代码>向量
将必然比向量
使用更多的内存,因为您有指针的开销和动态内存分配的开销。但是,如果您只有几个大对象,则此开销可能相对较小
但是,如果内存即将耗尽,如果无法提前保留正确的大小,则使用vector
可能会导致问题,因为在重新分配向量时,您将暂时需要额外的存储空间
拥有大型对象的大型向量也可能导致内存碎片问题。如果您可以在程序执行的早期创建向量并保留大小,这可能不是问题,但如果稍后创建向量,您可能会由于堆上的内存漏洞而遇到问题。在上述两个选项中,第三个未包含的选项是最有效的:
std::vector<Obj> someVector;
someVector.reserve(preCalculatedSize);
for (int i = 0; i < preCalculatedSize; ++i)
someVector.emplace_back();
这可能是最好的。这里,我们表示数据的生命周期,以及如何在相同的结构中以几乎零的开销访问数据,以防止数据失去同步
要移动时,必须显式地移动std::unique\u ptr
。如果出于任何原因需要原始指针,.get()
是如何访问它的->
和*
和显式运算符bool
都被重写,因此当您有一个需要Obj*
的接口时,您只需要调用.get()
这两种解决方案都需要C++11。如果您缺少C++11,并且对象确实很大,那么“数据指针向量”是可以接受的
在任何情况下,您真正应该做的是确定哪一个与您的模型最匹配,检查性能,并且只有在出现实际性能问题时才进行优化。在上述两个选项中,第三个未包含的选项是最有效的
std::vector< std::unique_ptr<Obj> > someVector;
std::unique_ptr<Obj> element( new Obj );
someVector.push_back( std::move(element) );