##对于溢出和越界的理解(overflow/outside range)
x86汇编flag寄存器有两个表示位, 分别位OF/CF, 溢出标志位/进位标志位
其中OF只对有符号数有效, 例如:
当两个1字节大小的数字相加时, A: 0111 1111 (127), B: 0000 0001 (1)
A + B = 128, 对应二进制位是 1000 0000, 但是对于有符号数来说, 这是负数, 计算结果是错误的
这里错误的原因是计算结果占用了一个不该它占有的有效位
不该它占有: 它占有了符号位, 这个位错误地被计算结果改变
有效: 这个符号位是被合理分配的, 并不是未定义的
CF只对无符号数有效, 例如:
当两个1字节大小的数字相加时, A: 1111 1111 (255), B: 0000 0001 (1)
A + B = 256, 对应二进制位是 1 0000 0000, 1字节大小存不下9bit, 计算结果无法保存, 产生错误
错误原因是: 计算结果超出了合理的范围, 这个位未被定义
同样不该它占有, 但是同时这是个未被定义的空间
那么就可以简单看出, 从寄存器角度, 溢出/越界的区分了, 那个位是否有效
(但是也不一定…)
vector<int> veci{1, 2, 3};
vector<int>::iterator it1 = veci.begin();
vector<int>::iterator it2 = veci.begin() + 1;
veci.erase(it1);
// @note 这里的erase会报错, 因为在上一句代码中, begin迭代器所指向的数据被删除了,
// 删除之后, begin迭代器之后的元素重新排序(往前移), 此时的it2已经不指向它原先希望指向的位置了
// 可能它指向了新的begin迭代器之后的位置, 也可能指向begin了, 直接的结果是: 它失效了
veci.erase(it2);
在上段代码中, it2实际可能还是指向一个元素的, (实际VS debug中, it2指向了第三个元素, 也就是3)
it2并未失效, 它依旧指向一块内存,(至少在VS debug中这样) 但是这是块不该它占有的内存
按照上述我们对溢出/越界的定义, 这种问题属于溢出
但是很可惜, 报错信息是:
“vector erase iterator outside range”
emmmmmmmmmm, 也就是说, 它认为这是越界…
所以我的理解可能是错的, 但是我还是认为这样子理解没有什么问题(大概… :) )
或许这样说更好, 有符号数, 只有7位数值, 两个7位数值无论如何计算也不会超过8位
而无符号数, 8位数值, 计算是可能超过8位的