You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:37:35