【发布时间】:2014-09-12 20:05:01
【问题描述】:
为简单起见,我将坚持使用vector<int>,但我认为这适用于任何vector<T> 对象。
如果我使用 vector<int>::iterator 来跟踪 int 向量中的某个位置,然后使用 vector<int>::push_back(),则迭代器将变得毫无价值。意思是,我不能用& 获取它的地址或取消引用它。一旦我在以下意义上打印了一些对象的地址,直接原因就有意义了:
vector<int> my_vec(1); //my_vec[0] = 0
vector<int>::iterator it = my_vec.begin(); //it -> my_vec[0], *it = my_vec[0] = 0
cout << "&my_vec = " << &my_vec << "\n";
cout << "&my_vec[0] = " << &my_vec[0] << "\n";
cout << "&it = " << &it << "\n"; //prints address, all good
cout << "*it = " << *it << "\n"; //prints 0, all good
cout << "\n\n" << pushing back..." << "\n\n";
my_vec.push_back(1);
cout << "&my_vec = " << &my_vec << "\n"; //same as before push_back()!
cout << "&my_vec[0] = " << &my_vec[0] << "\n"; //different from before push_back()!!
cout << "&it = " << &it << "\n"; //same as before push_back()
//cannot do &it or *it
所以很明显it 的地址没有改变,但push_back() 在内存中移动了一些东西,现在my_vec 的不同“元素”的地址被改变了。 my_vec[i] 有一个新地址这一事实对我来说很有意义,但我有以下问题:
1) 为什么my_vec的地址没有变化?似乎如果push_back() 导致my_vec[i] 的地址发生变化,它也应该改变整个对象的地址。对于数组,my_array 是指向my_array[0] 的指针,所以我可以想象一个操作会更改每个my_array[i] 的地址并更新指针以指向my_array[0] 的新地址,但指针@987654337 的地址@ 作为一个对象本身不会改变。但是my_vec 在任何意义上都不是指向my_vec[0] 的指针,所以我很困惑为什么my_vec[i] 的地址会改变,而对象my_vec 不会改变。
2) 为什么vector<int> 内部的任何更改my_vec[i] 地址的操作(例如push_back())也不能正确“更新”任何迭代器?这似乎是个好主意?没有?
3) 鉴于 #2 就是这样,并且当我调用 push_back() 时我的迭代器变得毫无价值,那么处理这个问题的正确方法是什么?如果我需要使用push_back(),我应该不使用迭代器吗?如果有人要抱怨我使用迭代器和push_back() 的用例,为了简洁起见,我将其排除在外,但它基本上是使用vector<int> 实现堆栈,我使用迭代器来跟踪顶部堆栈。由于我不想以固定大小开始,所以当我的迭代器命中my_vec.end() 时,我尝试使用push_back() 来扩大堆栈。但我认为总的来说这是一个有效的问题。
非常感谢您的帮助!
【问题讨论】:
-
你真的应该一次只问一个明确的问题。
-
@Blastfurnace,我根据你的评论删除了#4,但你的参考没有回答#2,这是我真正好奇的。
-
@juanchopanzo,我觉得他们都是密切相关的。
-
@river_jones:我认为最简单的解决方法是保存 indexes 而不是迭代器或指针。
my_vec[5]将始终是第六个元素,即使在发生插入、擦除或调整大小之后也是如此。 -
你的问题太长而且不可读,我什至没有读到最后,但是+1的声音标题,我有同样的问题。
标签: c++ vector iterator push-back