说一个非常重要的语法错误。
如果你写这样一句话:
v[x] = newnode();
其中:
v
为一个vector
。x
为不越界的非负整数,且不会变化。newnode()
函数内会向vector
内push_back
一个新元素,并返回加入元素(即最后一个元素)的下标。
那么,你会发现,v[x]
的值并不是这样变化的:
1,2,3,4,5,6,7,...
而是类似于这样的:(非真实输出结果,仅供参考)
1,1,2,2,3,4,4,5,6,7,8,8,9,10,11,12,13,14,15,16,16,17,18,19,20,...
你会发现部分情况下,v[x]
没有变化!
这实际上是因为vector
的内部机制。
vector
会有一个capacity
,就是提供的内存大小。
每次push_back
的时候,如果说加入后,不超过当前的capacity
,就会直接加入。
否则,vector
会新开辟一块等于当前capacity
的两倍(这个在不同编辑器上是不一样的,有些可能是每次新增 $5$ 个)的新空间,并把原本的数据拷进这块新空间内。
比如说现在的vector
是:
内存354~357位置:3 1 2 4
且capacity
是 $4$,那么我们如果尝试push_back
一个 $5$,则vector
就会发现大于了capacity
,便会新开一块等于当前capacity
的两倍的空间:
内存354~357位置:3 1 2 4
内存382~389位置:
并把当前数据拷进去:
内存354~357位置:3 1 2 4
内存382~389位置:3 1 2 4
然后在新空间内加入 $5$:
内存354~357位置:3 1 2 4
内存382~389位置:3 1 2 4 5
并把所有v[x]
指向的内存都改成382~389
这块新内存内对应的地方。
不过由于C++的赋值机制,系统会先找到要赋值给的变量的指针,然后求出要赋的值,赋给以前找到的指针。(这一步是推测,可能不准确)
所以就会导致把newnode()
的值赋给了原本的v[x]
,导致输出的时候访问的新v[x]
值出错。
解决方法也很简单,把newnode()
用个临时变量t
存储,并将v[x]
赋值为t
即可。