关于引用vector元素。。。

kiffa 2009-03-07 05:57:37
下面代码可能会输出什么?是否存在问题?

#include <vector>
#include <iostream>
using namespace std;

int main()
{
vector<int> ivec(3, 1);
int &i = ivec[2];
ivec.push_back(2);
i = 5;
cout << ivec[2] << endl;
}
...全文
540 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuysheng 2009-03-07
  • 打赏
  • 举报
回复
你这样出来的结果为1,不过,这个值不是一定的,好像在不同的编译器下是不一样的,
不过,在STL编程中,vector容器确实会二次分配内存..
vector <int> ivec(3, 1);
改成
vector <int> ivec(2, 1);
会出现不定值....


lovewwy 2009-03-07
  • 打赏
  • 举报
回复
学习了。
lovewwy 2009-03-07
  • 打赏
  • 举报
回复
学习了
hacker_sx 2009-03-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 neeestth 的回复:]
为什么要重新分配内存呢?
[/Quote]
不是说一定要重新分配内存,分不分配内存依赖于编译器,如果这里你用的编译器预留了额外的存储空间,那么这个存储空间还可以存储元素
则,楼主的程序(只插入一个元素),不需要重新分配内存,但如果你的编译器没有预留额外的存储空间,插入元素的时候,没地方可插了,就要重新分配内存

具体原因,可见9楼.
野男孩 2009-03-07
  • 打赏
  • 举报
回复
一开始只分配了3个元素的内存,后面又需要push_back一个元素,存在哪?

记住,vector是要保证数据在一片连续内存中的。所以它必须重新分配足够的内存,然后把原来的数据copy过去,把新数据写在后面,才能保证连续性。

[Quote=引用 10 楼 neeestth 的回复:]
为什么要重新分配内存呢?
[/Quote]
shexinwei 2009-03-07
  • 打赏
  • 举报
回复
不懂,UP!
hua_zhixing_ 2009-03-07
  • 打赏
  • 举报
回复
我运行了一下,应该是重新分配了。如果像下面那样,就是楼主想得到的结果。
int main()
{
vector<int> ivec(3, 1);
ivec.push_back(2);
int &i = ivec[2];
i = 5;
cout << ivec[2] << endl;
}
zhkefa 2009-03-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 neeestth 的回复:]
为什么要重新分配内存呢?
[/Quote]

vector是动态增长的,单原来分配的内存不够放下新数据时,就要重新分配快大的内存来(并把原来的内存拷过来,这里就会发生引用失效)。
eatsweetpotato 2009-03-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 akirya 的回复:]
当然存在问题了
ivec.push_back(2);
的时候
vector内部的数据可能发生重新分配内存的过程
之前保存的int&引用就可能无效.再赋值就有问题了.
[/Quote]

UP
neeestth 2009-03-07
  • 打赏
  • 举报
回复
为什么要重新分配内存呢?
hacker_sx 2009-03-07
  • 打赏
  • 举报
回复
在vector中添加元素可能会导致整个容器被重新加载(vector中的元素是连续存储的)

注意:这里是可能,并不是一定.

容器在定义的时候都会预留一些额外的存储空间(具体预留多少,依赖于内存分配的实现方式,不同的库采取不同的分配策略,也就是依赖编译器了)
用来存储新添加的元素
vector提供了两个成员函数,分别是capacity和reserve

capacity函数功能:该函数返回容器在必须分配新存储空间之前能够存储的元素个数
reserve函数功能:使用它可以显式的告诉编译器定义一个vector容器时预留多少个元素的空间

原因如下:

1.如果capacity函数返回大于0,则表明还可以添加元素,而且不需要重新加载容器,这样的话,引用不会失效,一切都是正确的
2.如果capacity函数返回为0,则表明容器中曾经预留的存储空间全部被用完了,要想再添加元素,则必须重新加载容器,在加载容器
的时候,编译器则会继续分配一些额外的存储空间,这个时候,引用全部失效,操作失效的引用,或者迭代器,都是不安全的,往往会产生错误的结果

例如:如果再添加那个元素时,容器本身预留的额外存储空间大于或者等于1(保证有足够的连续存储空间),则都不需要重新加载容器,引用迭代器都是有效的


#include <vector>
#include <iostream>
using namespace std;

int main()
{
vector<int> ivec(3, 1);
ivec.reserve(10);//显示告诉编译器预留10个元素的空间
//只要添加的元素<=10,则不会加载容器,引用是有效的
//但如果插入的元素>10,则容器会被重新加载,引用失效
int &i = ivec[2];
ivec.push_back(2);
i = 5;
cout << ivec[2] << endl;
}
mabo321 2009-03-07
  • 打赏
  • 举报
回复

#include <vector>
#include <iostream>
using namespace std;

int main()
{
vector<int> ivec(3, 1);
int &i = ivec[2];
ivec.push_back(2);
i = 5;
cout << ivec[2] << endl;
}


我的机子打出来 1
看来 就是 出现了 空间的重新分配……
zhkefa 2009-03-07
  • 打赏
  • 举报
回复
如果改下程序


vector<int> ivec(3, 1);
ivec.reserve(4); //这里分配足够的内存,i引用就不会失效
int &i = ivec[2];
ivec.push_back(2);
i = 5;
cout << ivec[2] << endl;
pengzhixi 2009-03-07
  • 打赏
  • 举报
回复
因为当你添加的元素个数超出了vector的容量时就会重新分配更大的内存,然后将久元素拷贝进去。
zhkefa 2009-03-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 chin_chen 的回复:]
引用 1 楼 akirya 的回复:
当然存在问题了
ivec.push_back(2);
的时候
vector内部的数据可能发生重新分配内存的过程
之前保存的int&引用就可能无效.再赋值就有问题了.


奇怪了,为啥这个时候一定要重新分配内存,我的机器上出错了。
[/Quote]

1楼说的很对了,这个时候不是一定会重新分配内存的,只是有可能会重新分配。
chin_chen 2009-03-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 akirya 的回复:]
当然存在问题了
ivec.push_back(2);
的时候
vector内部的数据可能发生重新分配内存的过程
之前保存的int&引用就可能无效.再赋值就有问题了.

[/Quote]
奇怪了,为啥这个时候一定要重新分配内存,我的机器上出错了。
lingyin55 2009-03-07
  • 打赏
  • 举报
回复
up too

[Quote=引用 1 楼 akirya 的回复:]
当然存在问题了
ivec.push_back(2);
的时候
vector内部的数据可能发生重新分配内存的过程
之前保存的int&引用就可能无效.再赋值就有问题了.
[/Quote]
pengzhixi 2009-03-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 akirya 的回复:]
当然存在问题了
ivec.push_back(2);
的时候
vector内部的数据可能发生重新分配内存的过程
之前保存的int&引用就可能无效.再赋值就有问题了.
[/Quote]

up
  • 打赏
  • 举报
回复
当然存在问题了
ivec.push_back(2);
的时候
vector内部的数据可能发生重新分配内存的过程
之前保存的int&引用就可能无效.再赋值就有问题了.

64,636

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧