C++ Vector无法判定为空问题求助:while循环无法终止
C++程序while循环永不终止问题排查
我是一名学习C++的学生,完成作业时遇到问题:程序中的while循环因simulation vector始终无法被清空而永不终止。程序逻辑是读取用户输入生成n个Aircraft对象存入simulation vector,随后在vector非空时,检查对象的自定义时间是否匹配当前模拟时间步,若匹配则将其存入优先堆并从原vector移除。
怀疑出错的代码片段
//collect aircraft data from cin vector<Aircraft> simulation; for (int i = 0; i < n; i++){ cin >> time >> id >> status >> priority; //create aircraft object Aircraft flight = Aircraft(time, id, status, priority); simulation.push_back(flight); } /*Start Simulation*/ time = 0; //while there are still scheduled flights while (!simulation.empty()) { cout << "Time step " << time << endl; cout << " Entering simulation" << endl; //for each flight scheduled in simulation for (int i = 0; i < simulation.size(); ++i) { //check if there are any flights entering simulation for time step if (simulation[i].getTime() == time) { simulation[i].printAircraft(); //Assign flight runway //Runway B prioritizes departures if (status == "departing" ) { A.push(simulation[i]); simulation.erase(simulation.begin() + i); //Runway A prioritizes arrivals } else if (status == "arriving") { B.push(simulation[i]); simulation.erase(simulation.begin() + i); } } time++; } //Print flights leaving simulation cout << " Runway A" << endl; if (!A.empty()) { A.peek().printAircraft(); A.pop(); } cout << " Runway B" << endl; if (!B.empty()) { A.peek().printAircraft(); A.pop(); } //increment time time++; }
完整程序代码
#include <iostream> #include <vector> #include <string> #include <memory> #include <algorithm> #include <climits> using namespace std; struct Aircraft { private: int id; int priority; int time; string status; public: //getter methods int getID() { return id; } int getPriority() { return priority; } int getTime() { return time; } string getStatus() { return status; } //Constructors Aircraft(){} Aircraft(int a, int b, string c, int d) { time = a; id = b; status = c; priority = d; } ~Aircraft(){} //print Aircraft void printAircraft() { cout << " " << time << " " << id << " " << status << " " << priority << endl; } }; struct Runway { private: vector<Aircraft> planes; //return parent of Aircraft at index i int PARENT(int i) { return (i - 1) / 2; } //return left child of Aircraft at index i int LEFT(int i) { return (2*i + 2); } //return right child of Aircraft at index i int RIGHT(int i) { return (2*i +2); } //This function compares Aircraft A & B, //returns true if A > B else false bool isPriority(int a, int b) { if (a && planes[b].getPriority() < planes[a].getPriority()) { return true; //else if priorities are the same check time } else if (a && planes[b].getPriority() == planes[a].getPriority()) { if (planes[b].getTime() < planes[a].getTime()) { return true; //else if time and priority are tied, check id } else if (planes[b].getTime() == planes[a].getTime()) { if (planes[b].getID() < planes[a].getID()) { return true; } } } return false; } //Recursive heapify-down /*Prioritization*/ void heapify_down(int i) { //get left and right index of aircraft being heapified int left = LEFT(i); int right = RIGHT(i); int smallest = i; //compare i with left and right child to find highest priority aircraft if (left < size() && isPriority(i, left)) { smallest = left; } if (right < size() && isPriority(i, right)) { smallest = right; } //if highest priority is not = i, that means that we must heapify down if (smallest != i) { swap(planes[i], planes[smallest]); heapify_down(smallest); } } //recursive heapify-up /*Priority: Priority, Time, ID*/ void heapify_up(int i) { //if Parent has higher priority than Aircraft at i then heapify up. if (isPriority(i, PARENT(i))) { swap(planes[i], planes[PARENT(i)]); heapify_up(PARENT(i)); } } public: unsigned int size() { return planes.size(); } bool empty() { return size() == 0; } void push(Aircraft a) { planes.push_back(a); int index = size() - 1; heapify_up(index); } void pop() { //check if the runway is empty if (!planes.empty()) { //replace root with last leaf planes[0] = planes.back(); planes.pop_back(); //heapify down on root heapify_down(0); } } Aircraft peek() { if (!planes.empty()) { return planes[0]; } return Aircraft(); } }; vector<Runway> makeAirport(); int main() { //initialize Runways Runway A; Runway B; //n = number of aircraft in simulation int n = -1; //initialize aircraft details int time = -1; int id = -1; string status = "Null"; int priority = INT_MAX; //read data from cin cin >> n; //check if valid number of aircraft was entered by user while (n <= 0) { cout << "Please enter a valid number of Aircraft..." << endl; cin >> n; } //collect aircraft data from cin vector<Aircraft> simulation; for (int i = 0; i < n; i++){ cin >> time >> id >> status >> priority; //create aircraft object Aircraft flight = Aircraft(time, id, status, priority); simulation.push_back(flight); } /*Start Simulation*/ time = 0; //while there are still scheduled flights while (!simulation.empty()) { cout << "Time step " << time << endl; cout << " Entering simulation" << endl; //for each flight scheduled in simulation for (int i = 0; i < simulation.size(); ++i) { //check if there are any flights entering simulation for time step if (simulation[i].getTime() == time) { simulation[i].printAircraft(); //Assign flight runway //Runway B prioritizes departures if (status == "departing" ) { A.push(simulation[i]); simulation.erase(simulation.begin() + i); //Runway A prioritizes arrivals } else if (status == "arriving") { B.push(simulation[i]); simulation.erase(simulation.begin() + i); } } time++; } //Print flights leaving simulation cout << " Runway A" << endl; if (!A.empty()) { A.peek().printAircraft(); A.pop(); } cout << " Runway B" << endl; if (!B.empty()) { A.peek().printAircraft(); A.pop(); } //increment time time++; } }
问题根源与修复方案
1. vector遍历与erase的错误
调用simulation.erase(simulation.begin() + i)后,vector中i位置之后的元素会自动前移一位,但循环里的i++会跳过下一个元素,导致部分元素永远没被处理。
修复方式:erase后不递增i,仅当元素不匹配时再递增:
for (int i = 0; i < simulation.size(); ) { if (simulation[i].getTime() == time) { // ... 处理逻辑 ... simulation.erase(simulation.begin() + i); // 不递增i,下一个元素已移到当前i位置 } else { i++; // 不匹配才递增索引 } }
2. status变量误用
判断跑道分配时,用的是main函数的局部变量status,而非当前simulation[i]的状态,导致判断完全错误,大部分元素无法被移除。
修复方式:替换为当前元素的状态,同时修正跑道分配的注释与代码不一致问题:
if (simulation[i].getStatus() == "departing" ) { B.push(simulation[i]); // B优先处理离场航班 simulation.erase(simulation.begin() + i); } else if (simulation[i].getStatus() == "arriving") { A.push(simulation[i]); // A优先处理到场航班 simulation.erase(simulation.begin() + i); }
3. time变量异常递增
for循环内每次执行time++,导致时间步跳得极快,后续Aircraft的getTime()远小于当前time,永远无法匹配,留在vector里。
修复方式:删除for循环内的time++,仅在while循环末尾统一递增时间:
while (!simulation.empty()) { cout << "Time step " << time << endl; cout << " Entering simulation" << endl; for (int i = 0; i < simulation.size(); ) { if (simulation[i].getTime() == time) { // ... 处理逻辑 ... } else { i++; } } // ... 跑道处理逻辑 ... time++; // 仅在此处递增时间步 }
4. Runway结构的其他错误
LEFT函数索引错误:正确左孩子索引应为2*i + 1,当前写成了2*i+2,导致堆结构异常;isPriority逻辑颠倒:当前条件会导致堆排序规则错误;- Runway B处理错误:调用了
A.peek()和A.pop(),应改为B.peek()和B.pop()。
这些错误虽不直接导致vector无法清空,但会引发程序逻辑混乱,需一并修复。
内容的提问来源于stack exchange,提问作者Boreas
相关产品推荐
相关产品推荐

