为何下述循环会执行?i远大于tmp.size()时循环仍运行的疑问
为啥明明i远大于tmp.size(),循环还在执行?
嘿,这个问题我之前踩过好几个坑,太懂这种看着代码一脸懵的感觉了!结合我自己的排查经验,大概率是这几种情况之一:
1. 数据类型不匹配导致的隐式转换坑
这是最常见的原因!很多容器的size()方法返回的是**size_t类型**(无符号整数),如果你用来比较的i是有符号整数(比如int),就会发生隐式类型转换,结果完全不符合你的预期。
举个典型的例子:
int i = -1; // 有符号负数 std::vector<int> tmp; // size()返回0(size_t类型,无符号) while (i < tmp.size()) { // 你以为i=-1 < 0是false?错! // int类型的-1会被转成无符号的size_t,变成一个超大的正数(比如4294967295) // 无符号数的比较是按二进制值判断,这个条件会变成true,循环一直跑! }
反过来,如果你的i是一个很大的有符号正数(比如超过int的最大值),转成无符号数后也可能出现奇怪的比较结果。
2. 循环体内悄悄修改了i或tmp的size
你以为i一直是那个远大于tmp.size()的值,但可能循环里的代码偷偷改了它俩:
- 比如
i在循环里被递减了:i--; - 或者
tmp被添加了元素:tmp.push_back(xxx);,导致tmp.size()不断变大,直到追上i - 甚至可能是其他代码(比如函数调用)间接修改了这两个变量
举个例子:
size_t i = 10; std::vector<int> tmp; while (i > tmp.size()) { tmp.push_back(1); // size从0慢慢涨到10 i--; // i从10慢慢降到0 // 这个循环会执行10次,看起来一开始i远大于size,但其实每次都在变化 }
3. 变量作用域搞混了
有时候你以为用的是外面的i,但循环里重新定义了一个同名的局部变量,导致循环条件判断的是外部的i(一直没变),而你操作的是内部的i:
int i = 100; // 外部的i,远大于tmp.size()=0 while (i > tmp.size()) { int i = 0; // 这里定义了局部的i,和外部没关系 // 你以为在改i,但其实外部的i还是100,循环条件永远为true,死循环! }
4. 多线程环境下的并发修改
如果你的代码是多线程的,可能其他线程在偷偷修改i或者tmp的大小,导致你看到的i和size()不是同一时刻的数值,循环条件就一直成立。
快速排查建议
- 先在循环的第一行打印实际的数值和类型:
看看是不是和你以为的数值/类型一致。cout << "i: " << i << ", 类型: " << typeid(i).name() << endl; cout << "tmp.size(): " << tmp.size() << ", 类型: " << typeid(tmp.size()).name() << endl; - 检查循环体内所有修改
i和tmp的代码,包括调用的函数里有没有间接修改它们。 - 确认变量的作用域,有没有重复定义同名变量。
- 如果是多线程,加个锁或者打印线程ID,看看是不是并发修改导致的。
我当初第一次碰到这个问题,就是把int和size_t混着用,隐式转换坑了我半天,打印出类型之后才恍然大悟!
内容的提问来源于stack exchange,提问作者Bula
相关产品推荐
相关产品推荐

