C++中List异常行为:欧拉回路程序加无关代码后恢复正常
欧拉回路程序添加无关代码后恢复正常的原因分析
我编写欧拉回路程序时,原本代码无法输出正确结果,但在for循环结束后添加一行看似无关的代码后,程序恢复正常运行,想知道该现象的原因。
原程序代码片段
/* A is a vector of lists that, where A[i] is the list of edges from vertex i. */ /* perform checks for even degree, then find a non-isolated vertex to begin the tour */ int u; for (u = 0; u < A.size() && A[u].empty(); u++) while (!A[u].empty()) { cout << u << "->"; int v = A[u].front(); A[u].pop_front(); u = v; } cout << u << endl;
添加的代码行
cout << u << A[u].size() << endl;
原因分析
问题的核心是原代码存在数组越界的未定义行为,添加的代码只是巧合改变了未定义行为的表现:
for循环的逻辑漏洞:
你原本想用for循环找到第一个非孤立顶点(A[u]不为空的u),但原代码中for循环后没有加终止分号或花括号,不过这不是致命问题。真正的问题是:当所有顶点都是孤立点(所有A[u]为空)时,for循环会执行到u = A.size()才退出,此时u已经超出了vector A的合法下标范围(vector下标合法范围是0到A.size()-1)。未定义行为的触发:
退出for循环后,代码执行while (!A[u].empty()),此时访问A[u]属于越界访问——这在C++中是未定义行为。未定义行为的表现完全不可控:可能输出错误结果、程序崩溃,甚至看似正常运行,具体取决于编译器优化、内存布局等随机因素。添加代码后的巧合:
你添加的代码同样存在越界访问A[u]的问题,但这行代码的执行可能改变了编译器的优化策略,或是恰好覆盖了之前越界访问导致的内存异常,让程序表现“恢复正常”。但这只是巧合,原代码的逻辑漏洞并没有被真正修复。
正确的修复方式
要彻底解决问题,需先处理u越界的情况,同时修正for循环的写法:
int u = 0; // 找到第一个非孤立顶点,循环体为空(加终止分号) for (; u < A.size() && A[u].empty(); u++); // 先判断u是否合法,再执行遍历 if (u < A.size()) { while (!A[u].empty()) { cout << u << "->"; int v = A[u].front(); A[u].pop_front(); u = v; } cout << u << endl; } else { // 处理所有顶点都是孤立点的情况 cout << "No edges in graph" << endl; }
内容的提问来源于stack exchange,提问作者ihsingh2
相关产品推荐
相关产品推荐

