vector中push_back后iterator程序崩溃的原因分析

一、首先必须弄清楚两个概念:

  1. capacity:指容器在分配新的存储空间之前能存储的元素总数。
  2. size:指当前容器所存储的元素个数
    由于vector对象在插入或添加时自动调整长度(注意:只会自动增加长度,不会自动减小长度),因此可以将vector的长度设置成0;当然,也可指定存储长度:
vector<typename> objection_name(n_elem);//存储n_elem个类型为typename的元素;

二、push_back()

push_back()成员函数的作用是在容器尾部添加一个元素。

三、push_back后iterator程序崩溃的原因分析

先看以下程序:

#include<iostream>
#include<vector>
using namespace std;
void display(vector<int>::iterator &p_num_,vector<int> &num_ )
{
	while (p_num_ != num_.end())
	{
		cout << *p_num_ << endl;
		p_num_++;
	}
}
int main()
{
	vector<int> num(100);
	num = { 1,2,3,4,5,6 };
	cout << "the capacity of num :" << num.capacity() << endl;
	vector<int>::iterator p_num = num.begin();
	display(p_num, num);
	int a[5] = { 11,22,33,44,55 };
	for (int i = 0; i < 5; i++)
	{
		num.push_back(a[i]);
		cout << "after " << i << "  push_back() the capacity is:" <<num.capacity()<< endl;
	}
	display(p_num, num);//error!!!
	system("pause");
	return 0;
}

在第二次display时出现错误,究其原因如下:

vector容器是动态分配内存的,在初始化1,2,3…,6后,当前的vector对象num的大小是6,若此时通过push_back()向num中添加元素,此时,编译器会重新分配一段内存用来保存此时的所有元素。而此时,迭代器p_num里面存放的依然是为扩容之前的地址,扩容后(由于是动态内存分配)num对象的地址发生改变,原来的p_num指向的是一块未知的内存空间,造成内存泄漏;

四、改进

#include<iostream>
#include<vector>
using namespace std;
void display(vector<int>::iterator &p_num_,vector<int> &num_ )
{
	while (p_num_ != num_.end())
	{
		cout << *p_num_ << endl;
		p_num_++;
	}
}
int main()
{
	vector<int> num(100);
	num = { 1,2,3,4,5,6 };
	cout << "the capacity of num :" << num.capacity() << endl;
	vector<int>::iterator p_num = num.begin();
	display(p_num, num);
	int a[5] = { 11,22,33,44,55 };
	for (int i = 0; i < 5; i++)
	{
		num.push_back(a[i]);
		cout << "after " << i << "  push_back() the capacity is:" <<num.capacity()<< endl;
	}
	vector<int>::iterator p_num_= num.begin();
	display(p_num_, num);//重新定义一个迭代器p_num_;
	system("pause");
	return 0;
}

五、验证

#include<iostream>
#include<string>
#include<vector>
using namespace std;
const int MAXNUM = 5;
int main()
{
	vector<int> num_data;
	cout << num_data.capacity() << endl;
	for (int i = 0; i < MAXNUM; i++)
	{
		num_data.push_back(i);
		cout <<"realtime capacity of vector:"<< num_data.capacity() << endl;
		cout << "the address of first number:" << &num_data[0] << endl;
	}
	vector<int> num_data_1(10);
	for (int i = 0; i < MAXNUM+10; i++)
	{
		num_data_1.push_back(i);
		cout << "realtime capacity of vector:" << num_data_1.capacity() << endl;
		cout << "the address of first number:" << &num_data_1[0] << endl;
	}
	system("pause");
	return 0;
}
}
0
realtime capacity of vector:1
the address of first number:00751638
realtime capacity of vector:2
the address of first number:00752550
realtime capacity of vector:3
the address of first number:00752908
realtime capacity of vector:4
the address of first number:00753498
realtime capacity of vector:6
the address of first number:0074DFF0
realtime capacity of vector:15
the address of first number:00752FA8
realtime capacity of vector:15
the address of first number:00752FA8
realtime capacity of vector:15
the address of first number:00752FA8
realtime capacity of vector:15
the address of first number:00752FA8
realtime capacity of vector:15
the address of first number:00752FA8
realtime capacity of vector:22
the address of first number:00745040
realtime capacity of vector:22
the address of first number:00745040
realtime capacity of vector:22
the address of first number:00745040
realtime capacity of vector:22
the address of first number:00745040
realtime capacity of vector:22
the address of first number:00745040
realtime capacity of vector:22
the address of first number:00745040
realtime capacity of vector:22
the address of first number:00745040
realtime capacity of vector:33
the address of first number:0074A0E8
realtime capacity of vector:33
the address of first number:0074A0E8
realtime capacity of vector:33
the address of first number:0074A0E8
请按任意键继续. . .

可见,在未确定vector对象的容量时,每进行一次push_back()就重新分配一段内存。
若第定义vector对象的大小后,当空间未被存储满时,不会动态分配内存,仅当内存空间不够时,才重新分配空间;
注意:
在指定vector对象num大小后,通过num.capacity()返回的空间总比定义的高处50%;

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,thrust的device_vector不支持使用push_back函数。这是因为在GPU上,需要使用连续的内存来存储数据,而push_back会导致内存重新分配和复制,从而破坏了内存的连续性。 相反,可以使用thrustpush_back_iterator来将数据添加到device_vector。使用push_back_iterator时,需要先创建一个迭代器对象,然后将其传递给thrust的算法函数,该函数将在迭代器指向的位置插入新的元素。 以下是一个使用push_back_iterator的示例代码: ```c++ #include <thrust/device_vector.h> #include <thrust/copy.h> #include <thrust/iterator/constant_iterator.h> #include <thrust/iterator/counting_iterator.h> #include <thrust/iterator/permutation_iterator.h> #include <iostream> int main() { thrust::device_vector<int> vec(5, 1); thrust::counting_iterator<int> first(10); thrust::counting_iterator<int> last = first + 5; thrust::copy(first, last, thrust::make_permutation_iterator(vec.begin(), vec.begin() + 2)); // print the contents of vec std::cout << "vec: "; thrust::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; return 0; } ``` 在这个例子,我们使用了thrust::make_permutation_iterator函数创建了一个迭代器对象,该对象使用了vec.begin()和vec.begin() + 2作为参数,该迭代器可以插入新的元素。然后,我们使用thrust::copy函数将从first到last的元素复制到vec,使用了创建的迭代器来指定插入位置。 希望这个回答可以帮助到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值