C++动态数组std::vector的使用与优化
创作时间:
作者:
@小白创作中心
C++动态数组std::vector的使用与优化
引用
CSDN
1.
https://m.blog.csdn.net/lixiaorong222/article/details/145481778
在C++的标准模板库STL中,包含了很多容器的数据结构,其中vector(向量)是一种动态数组,其大小可以动态变化。本文将详细介绍vector的使用方法和优化技巧。
vector的基本使用
vector在内存中是连续存储的,可以使用push_back方法添加元素。下面是一个简单的示例:
#include <iostream>
#include <vector>
struct Vertex {
float x, y, z;
};
std::ostream& operator<<(std::ostream& stream, const Vertex v) {
stream << v.x << "," << v.y << "," << v.z;
return stream;
}
void print(const Vertex& v) {
std::cout << v << std::endl;
}
int main() {
std::vector<Vertex> vertexs;
vertexs.push_back({1, 2, 3});
vertexs.push_back({4, 5, 6});
for (int i = 0; i < vertexs.size(); ++i) {
std::cout << vertexs[i] << std::endl;
}
vertexs.erase(vertexs.begin() + 1);
std::cout << "after erase:" << std::endl;
for (Vertex& v : vertexs) {
std::cout << v << std::endl;
}
std::cout << "size:" << vertexs.size() << std::endl;
std::cout << "capacity:" << vertexs.capacity() << std::endl;
vertexs.clear();
std::cout << "after clear:" << std::endl;
for (Vertex& v : vertexs) {
print(v);
}
std::cout << "size:" << vertexs.size() << std::endl;
std::cout << "capacity:" << vertexs.capacity() << std::endl;
vertexs.shrink_to_fit();
std::cout << "after shrink_to_fit:" << std::endl;
std::cout << "size:" << vertexs.size() << std::endl;
std::cout << "capacity:" << vertexs.capacity() << std::endl;
std::cin.get();
}
输出结果表明:
- clear和erase只会改变数组大小,删除元素内容,但不会销毁内存capacity;
- shrink_to_fit会将内存调整到和数组大小一样大。
vector的内存管理机制
当vector容量不足时,需要将旧内存空间中的所有元素都拷贝进新内存空间中去,之后再在新内存空间中的原数据的后面继续进行插入构造新元素,并且同时释放旧内存空间。这也是vector动态扩容的机制。起始容量为0,不同编译器的扩容策略可能不同,例如GCC是2倍扩容,VS13是1.5倍扩容。
vector的优化技巧
使用emplace_back代替push_back
push_back总是会调用拷贝构造函数,而emplace_back支持直接传入构造函数需要的参数,不会调用拷贝构造函数,直接在数组中构造元素。下面是一个对比示例:
#include <iostream>
#include <vector>
class Vertex {
private:
int x, y, z;
public:
Vertex(int x, int y, int z) : x(x), y(y), z(z) {}
Vertex(const Vertex& v) : x(v.x), y(v.y), z(v.z) {
std::cout << "copy func()" << std::endl;
}
};
int main() {
std::vector<Vertex> vertexs;
vertexs.reserve(5);
std::cout << "capacity:" << vertexs.capacity() << " size:" << vertexs.size() << std::endl;
Vertex v(1, 2, 3);
std::cout << "push_back instance object:" << std::endl;
vertexs.push_back(v); // copy func()
std::cout << "emplace_back instance object:" << std::endl;
vertexs.emplace_back(v); // copy func()
std::cout << "push_back temp object:" << std::endl;
vertexs.push_back(Vertex(1, 2, 3)); // copy func()
std::cout << "emplace_back temp object:" << std::endl;
vertexs.emplace_back(Vertex(1, 2, 3)); // copy func()
std::cout << "emplace_back construct func:" << std::endl;
vertexs.emplace_back(1, 2, 3); // 不调用拷贝函数
return 0;
}
使用reserve预分配内存
reserve用于预分配内存,避免动态增长造成的开销。下面是一个使用reserve和resize的对比示例:
std::vector<Vertex> vertexs;
vertexs.reserve(10);
std::cout << "size:" << vertexs.size() << std::endl; // 0
std::cout << "capacity:" << vertexs.capacity() << std::endl; // 10
vertexs.reserve(0);
std::cout << "size:" << vertexs.size() << std::endl; // 0
std::cout << "capacity:" << vertexs.capacity() << std::endl; // 10
vertexs.push_back({1, 2, 3});
vertexs.push_back({4, 5, 6});
std::cout << "size:" << vertexs.size() << std::endl; // 2
std::cout << "capacity:" << vertexs.capacity() << std::endl; // 10
vertexs.resize(1);
std::cout << "size:" << vertexs.size() << std::endl; // 1
std::cout << "capacity:" << vertexs.capacity() << std::endl; // 10
vertexs.resize(20);
std::cout << "size:" << vertexs.size() << std::endl; // 20
std::cout << "capacity:" << vertexs.capacity() << std::endl; // 20
总结
为了优化vector的性能,可以采取以下措施:
- 使用reserve进行内存预分配;
- 使用emplace_back进行传参添加元素;
- 使用引用传递数组。
热门推荐
法院开庭程序有哪些
紫甘蓝生吃可不可以
心脏康复——让心梗患者重获“心”生!
以宣纸为媒 展墨韵万变
以宣纸为媒 展墨韵万变
如何合理判断黄金的最高价格水平?这样的判断依据是什么?
字母与阿拉伯书法:沙特里亚尔官方货币符号正式发布
如何在朗诵中掌握好节奏感?
犯罪程度不同惩罚理应有别——法律视角下的刑罚公平性探讨
生产力发展战略助力经济腾飞的新路径
幼儿绘本讲述与演绎:叙述语言表达技巧详解
“医保专员”:看病就医贴心小管家
养老院棋牌室效果图设计:舒适与便捷并重的社交空间
IntelliJ IDEA插件开发之国际化配置
好看≠好用!让你的肌肉既有型又有实力!
数字电路设计:两种序列检测方法详解
最后的默契,就是互不打扰
蒙台梭利教育体系:以儿童为中心的教育理念与实践
体育课天天见,小身板天天练!看这些地方,孩子们活力满满→
三明治的热量及营养成分
最近流行说"天花板"是什么意思?从流行语到实际应用的多重解读
诊疗更进一步,多学科协作助力肿瘤患者健康长生存
双马尾数字人怎么画的
科普一下:食物不耐受怎么查(附食物不耐受检测流程和方法)
聚餐饮酒后意外受伤,同桌共饮者是否需要承担责任?
网传三种“致癌蔬菜”真相:适量食用无须过度担忧
济南带孩子一日游攻略,这三条线路总有一条适合你
遭遇暴力事件后的法律救济与赔偿
呕吐时可以喝葡萄糖吗?这取决于呕吐的原因
春节福字的文化内涵