vector中end()和begin()本身值的疑问

airwolf1216 2012-04-24 11:37:10

#include <vector>
using namespace std;
using std::vector;
#include <stdio.h>

void main()
{

vector<int> iv1;

vector<int>::iterator itve1;

for(int i=0;iv1.size()!=1000;i++)
{
iv1.push_back(i);//在vector中存入1000个元素
}

printf("======%d\n",iv1.begin());
printf("======%d\n",iv1.end());
}




为什么begin()位置的值和end()位置的值是一样的?
vector不是顺序存储的吗?按道理,end()要比begin()大的,以递增的关系……
...全文
1255 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
姚昕 2012-04-30
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 的回复:]

C/C++ code

#include <iostream>
#include <vector>
#include <stdio.h>
using namespace std;

int main()
{
vector<int> v;
for(int i=1; i<10;i++)
v.push_back(i);

……
[/Quote]
vector的begin()返回第一个元素的地址,end()返回最后一个元素的下一个地址没错,所以你要返回值的时候应该这样。printf("======%d\n",*iv1.begin());
printf("======%d\n",*(iv1.end()-1));
而在我电脑上不管是返回地址还是值,内容都是不一样的。
xystcz 2012-04-29
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 的回复:]

引用 42 楼 的回复:
建议楼主写代码时,少用using 关键字, 尽量限制使用

不用using 能用list吗
[/Quote]

std::list,真心觉得20楼戳中了重点。
xystcz 2012-04-29
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 的回复:]

引用 42 楼 的回复:
建议楼主写代码时,少用using 关键字, 尽量限制使用

不用using 能用list吗
[/Quote]

std::list,真心觉得20楼戳中了重点。
airwolf1216 2012-04-28
  • 打赏
  • 举报
回复
[Quote=引用 42 楼 的回复:]
建议楼主写代码时,少用using 关键字, 尽量限制使用
[/Quote]
不用using 能用list吗
hjgy 2012-04-28
  • 打赏
  • 举报
回复
建议楼主写代码时,少用using 关键字, 尽量限制使用
hjgy 2012-04-28
  • 打赏
  • 举报
回复
关于楼主的list随机存储的问题,原因是stl实现了小对象内存池.因为大量的小对象申请对造成性能的下降,所以干脆申请一个内存池,里面放了好多已经申请好的内存块,这些块由于是一次申请一个大块分隔的,所以他们内存中是相连的.这样,当需要小对象的时候,直接从内存池中返回相应的块,释放时,就在归还到内存池就得了.

对于大对象,申请的时间开销跟维护内存池的内存开销矛盾,所以对于大对象,不会使用内存池

stl里面好像128B是个门阀值, 按2^n向上取整后,只要小于128B的,都走内存池,大的,就走原生的分配了.

可以定义一个 struct TestType{ char value[129];}进行测试.测试完了,跟大家讲下结果.
kanaverdet 2012-04-26
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 的回复:]
爬了几楼发现,无论怎么解释楼主都不会懂的,因为楼主太菜了。去看看stl的代码吧,先把运算符重载和模版学好再来去跟别人演示。
[/Quote]
同意
zhanglingxiang 2012-04-26
  • 打赏
  • 举报
回复
都是神人啊!!学习了
eliteRubin 2012-04-26
  • 打赏
  • 举报
回复
迭代器里面除了指针还封装了很多其它的东西。不是迭代器支持一般的指针操作它就是指针,部分情况下它能当指针使用。在很多把C++特性的东西传给底层C API时都会有这样的问题。
haha_ 2012-04-25
  • 打赏
  • 举报
回复
爬了几楼发现,无论怎么解释楼主都不会懂的,因为楼主太菜了。去看看stl的代码吧,先把运算符重载和模版学好再来去跟别人演示。
iamnobody 2012-04-25
  • 打赏
  • 举报
回复
http://en.cppreference.com/w/cpp/container/vector
iamnobody 2012-04-25
  • 打赏
  • 举报
回复
回13:

规律可能来自: 1.系统分配动态内存的算法.
2.std::list<> 的第二个模板参数决定的Allocator 使用的算法.(可能采用内存池);


无论如何,试多几个元素,总会有不合规律的.


回15:

那是编译器的非标准拓展.不应该使用.


回16:
1.用printf 输出我不重复了,见楼上.
2.标准规定vector 的内存是连续的,如同数组一般.
assefan 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

引用 10 楼 的回复:
楼主可以这样试一下 用C++的方法输出 cout << iv1.begin() << endl; cout << iv1.end() << endl; 这样使出的值就正确了 在我的机子上是 003833D8 00384378 每个人的机子上应该不一样。

你用的什么编译器能通过这种写法?
我用的vs2008 这样写报错
[/Quote]

我用的是VC6.0
ljhhh0123 2012-04-25
  • 打赏
  • 举报
回复
楼主的眼睛花了吧。
#include <vector>

#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
vector<int> iv1;

for(int i=0;iv1.size()!=1000;i++)
{
iv1.push_back(i);//在vector中存入1000个元素
}

printf("======%d\n",iv1.begin());
printf("======%d\n",iv1.end());

return 0;
}

值并不一样。如果你没有push_back数据,那肯定是一样的。
另外,C++标准并没有规定end()必须大于begin()的值,vector申请的内存块更不必是连续的。
而只规定了前闭后开的区间用来遍历,它们相等就代表遍历完了。
airwolf1216 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]
对于list,LZ可以尝试着随机删除/插入一些节点,也许可以看到期望的结果。
不管怎样,看debugger中的memory dump会理解的更深入。
[/Quote]
这个方法倒是不错
airwolf1216 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
楼主可以这样试一下 用C++的方法输出 cout << iv1.begin() << endl; cout << iv1.end() << endl; 这样使出的值就正确了 在我的机子上是 003833D8 00384378 每个人的机子上应该不一样。
[/Quote]
你用的什么编译器能通过这种写法?
我用的vs2008 这样写报错
assefan 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

void main()
{

vector<int> iv1;

//vector<int>::iterator itve1;

for(int i=0;iv1.size()!=1000;i++)
{
iv1.push_back(i);//在vector中存入1000个元素
}

printf("======%d\n",iv1.begin());
pri……
[/Quote]

我错了 是一样的 cout输出的是16进制的
airwolf1216 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

迭代器的值是什么?你需要好好想想这个问题.

在这里,迭代器就是一个类,它里面有各种成员,printf 只能输出基本类型.把整个类的对象作为参数是不合法的.


……
[/Quote]
好吧,这种方式的确能输出迭代器的值了
其实我的目的是向别人演示list容器存储的随机性 结果我发现:

#include <list>
using namespace std;
using std::list;
#include <stdio.h>

void main()
{

list<int> iv1;

list<int>::iterator itve1;

for(int i=0;iv1.size()!=1000;i++)
{
iv1.push_back(i);//在list中存入1000个元素
}
itve1=iv1.begin();

int *p = &*itve1;
printf("======%d\n",p);
itve1++;
p = &*itve1;
printf("======%d\n",p);
itve1++;
p = &*itve1;
printf("======%d\n",p);
itve1++;
p = &*itve1;
printf("======%d\n",p);
itve1++;
p = &*itve1;
printf("======%d\n",p);
itve1++;
p = &*itve1;
printf("======%d\n",p);
itve1++;
p = &*itve1;
printf("======%d\n",p);
itve1++;
p = &*itve1;
printf("======%d\n",p);
}


输出结果居然很有规律,虽然不是间隔4,但是间隔固定的数字,让我哑口无言。难道list的随机存储,还这样有迹可循?
assefan 2012-04-25
  • 打赏
  • 举报
回复
void main()
{

vector<int> iv1;

//vector<int>::iterator itve1;

for(int i=0;iv1.size()!=1000;i++)
{
iv1.push_back(i);//在vector中存入1000个元素
}

printf("======%d\n",iv1.begin());
printf("======%d\n",iv1.end());

cout << iv1.begin() << endl;
cout << iv1.end() << endl;

}

在我的机子上输出结果为

======3683288
======3687288
003833D8
00384378
Press any key to continue

值竟然不一样
iamnobody 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 5 楼 的回复:
引用 3 楼 的回复:

迭代器 不可以看作指针吗?指针不可以用%d吗


指针是一种迭代器,但是迭代器不能看作指针.

vector 的迭代器有与普通指针一样的操作.所以看起来像.

把迭代器当作指针,这是一个入门教材为了省事而写出的话,不可信.


2.指针不可以用 %d ,这个错误实在太普遍了..指针应该用 %p


话说 这个%p……
[/Quote]

不是照用不误 ,而是有误照用.

都说了是未定义的,百度未定义行为.

加载更多回复(25)

64,639

社区成员

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

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