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进行传参添加元素;
- 使用引用传递数组。
热门推荐
哥斯拉奇异点(宇宙学)
与《哈利波特》齐名全世界现象级经典,火爆全网的猫武士是一套“全能”的好书?
《道德经》其实很实用第72章:千年传承,社会管理的典范
如何正确填写劳动仲裁申请书范本?
宝宝生长曲线怎么看
多地探索“无陪护”病房 全面推广尚待时日
如何不断提高自己的审美水平?
如何快速判断斯诺克哪颗球超分?
2025年黑龙江省高校排名:哈医科第3,哈商大第15,大庆师院第25
考研国家线:分数是怎么设定出来的?
率土之滨十大强势队伍 最强10套
八字命理中“金生水”的含义及其影响是什么
旋涡泵的工作原理与主要用途
深圳人形机器人行走视频走红,英伟达科学家点赞
高铁上可以带奶茶吗?这些细节要注意
震荡市中如何挑选权益基金?
最高院一锤定音:经济补偿金的前12个月平均工资这样计算!
高氯血症的临床表现及危害
探索三清山的神秘与美丽
斑块会缩小或消失吗?发现「颈动脉斑块」都需要吃阿司匹林、他汀吗?
手机投屏完全指南:安卓Miracast与苹果AirPlay使用详解
为什么山东高考分数线那么高 原因有哪些 附山东历年高考分数线!
抑郁症测评表怎么看结果
耳熟能详的“失信被执行人”你真的了解吗?
舟山普陀区最美6大古村落,海天佛国风光静美
几百到几万甚至几十万,无人机的价格到底差在哪?
《人民日报》:让候鸟老人丝滑融入,六盘水做好康养“凉文章”
孩子学习没兴趣怎么办?5个方法让他重新爱上学习
服用优甲乐期间可以吃豆制品吗?
麻省理工和宾大重磅宣布:家庭收入低于$20万,直接免学费!