本文总结vector的原理和使用方法。
1 vector的实现原理
1.2 vector保存在栈上还是堆上?
- 示例代码1:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
vector<int>* test_vec(void) {
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
return &vec;
}
int main()
{
vector<int>* o_vec = test_vec();
printf("%d\n", (*o_vec)[0]);
return 0;
}
|
在编译时会有如下提示:warning: reference to local variable 'vec' returned [-Wreturn-local-addr]。
而忽略该告警直接编译运行,进程会coredump。
- 示例代码2
1
2
3
4
5
6
7
8
9
10
11
12
13
|
vector<int> test_vec(void) {
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
return vec;
}
int main()
{
vector<int> o_vec = test_vec();
printf("%d\n", o_vec[0]);
return 0;
}
|
该段代码可以正常编译运行,无任何报错。
- 示例代码3
1
2
3
4
5
6
7
8
9
10
11
12
13
|
vector<int>* test_vec(void) {
vector<int>* vec = new vector<int>;
vec->push_back(1);
vec->push_back(2);
return vec;
}
int main()
{
vector<int>* o_vec = test_vec();
printf("%d\n", (*o_vec)[0]);
return 0;
}
|
这段代码可以正常运行。
原因分析:
- 为什么示例代码1和实例代码2中的函数test_vec()相同,为啥返回vector变量的地址会coredump,而直接将vector的名字返回却可以正常运行呢?
答:因为C++ 11新特性中支持直接返回容器名会默认调用move()函数,参考1.3.1和1.3.2的内容。
1.3 C++中返回一个vector的方法
1.3.1 通过value返回
1
2
3
4
5
6
|
#include <vector>
std::vector<int> createVector() {
std::vector<int> vec = {1, 2, 3, 4, 5};
return vec; // Move semantics will be applied here
}
|
1.3.2 通过move()函数
1
2
3
4
|
std::vector<int> createVector() {
std::vector<int> vec = {1, 2, 3, 4, 5};
return std::move(vec); // Explicitly moving the vector
}
|
1.3.3 返回静态引用
1
2
3
4
|
std::vector<int>& getGlobalVector() {
static std::vector<int> vec = {1, 2, 3, 4, 5};
return vec; // Return a reference to a static vector
}
|
1.3.4 通过传入引用实现
1
2
3
|
void fillVector(std::vector<int>& vec) {
vec = {1, 2, 3, 4, 5}; // Modify the existing vector
}
|
1.3.5 使用std::optional
1
2
3
4
5
6
7
8
9
|
#include <optional>
#include <vector>
std::optional<std::vector<int>> createVector(bool shouldCreate) {
if (shouldCreate) {
return std::vector<int>{1, 2, 3, 4, 5};
}
return std::nullopt; // No vector created
}
|
相关参考文档:
Is there a way to return a vector more efficiently
一文带你详细介绍c++中的std::move函数
【Modern C++】深入理解左值、右值
2 vector的使用方法
2.1 vector初始化的方法
1
2
3
4
5
6
7
|
std::vector<int> first; // empty vector of ints
std::vector<int> second(4, 100); // four ints with value 100
std::vector<int> third(second.begin(),second.end()); // iterating through second
std::vector<int> fourth(third); // a copy of third
int tmp[] = { 10, 20, 30 };
std::vector<int> v(tmp, tmp + 3 ); // use some utility to avoid hardcoding the size here
|
2.2 vector容量相关
1
2
3
|
std::vector<int> vec(3, 235);
vec.size(); // return the number of elements
vec.empty(); // checks whether the container is empty
|
2.3 vector数据修改
1
2
3
|
std::vector<int> vec(3, 235); // init vector
vec.push_back(12); // adds an element to the end
vec.pop_back(); // removes the last element
|