最近在写程序的时候,由于对vector机制的不了解,往全局作用域的std::vector中添加数据的时候总是束手束脚,今天抽空做了点实验,对std::vector有了进一步的认识,贴出来记录一下。
下面贴一些伪代码流程,程序输出结果省略,直接写结论。
//定义一个测试类
class testClass {
public:
int val;
testClass(int a) {
val = a;
printf("hello,my point is %p,my value is %d\n", this, val);
};
testClass(const testClass& t) {
val = t.val;
printf("copy,my point is %p,my value is %d\n", this, val);
}
~testClass() {
printf("byebye,my point is %p,my value is %d\n", this, val);
}
void say() {
printf("say,my point is %p,my value is %d\n", this, val);
}
};
//定义三种类型的vector
std::vector<float> vecValue;
std::vector<float*> vecArray;
std::vector<testClass> vecClass;
void subfunc(){
//往上述三个类型的vector添加一些数据
}
void print_info(){
//打印vector里的数据及其地址
}
void main(){
subfunc();//添加数据
...//一些计算量大的程序,用于将subfunc里被释放的内存覆盖
print_info();//打印数据信息
}
单次测试:[全局]std::vector存储[局部作用域]的基本数据类型
在push_back的时候,会将局部数据的值拷贝到vector的指定的内存区域,之后局部数据在生命周期结束后释放。
单次测试:[全局]std::vector存储[局部作用域]的指针类型
在push_back的时候,会将局部数据值的地址拷贝到vector的指定的内存区域,之后局部数据在生命周期结束后释放。在后续访问该指针指向的数据区域时候,一般会访问失败。
单次测试:[全局]std::vector存储[局部作用域]的对象
在push_back的时候,会调用局部对象的拷贝构造函数,将拷贝对象存储到vector中,之后局部对象在生命周期结束后释放。
总的结论
(一)全局vector在push_back局部数据时,会将数据做拷贝后存储在vector指向的对应内存区域
- 对于基本数据类型,相当于直接赋值,问题不大,放心使用。
- 对于指针类型,显然拷贝的只是指针的值,所指向内存区域的数据不会做拷贝,如果这块内存区域数据被释放,访问仍然会产生错误。可以使用new来开辟内存,防止系统自动释放。
- 对于对象类型,会调用其拷贝构造函数,生成一个拷贝对象存放到vector中。
(二)vector在push_back时候,如果超过当前的存储空间,则会重新开辟一块更大的内存区域,将所有数据都拷贝过去,这是非常耗时的,特别是对于存储对象来说,因此尽可能先用reserve()函数预先分配空间。