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

C++程序while循环异常:执行一次迭代后直接退出问题求助

问题分析与修复

你的程序看似循环只执行一次就退出,本质是Ship类中的Address* address是未初始化的野指针,调用address->set(r, c)时触发了未定义行为,导致程序直接崩溃,而非正常退出循环。

核心修复步骤

1. 解决野指针问题

野指针是导致程序崩溃的根源,必须确保address指向有效的内存空间,以下两种方案任选其一:

方案一:给Ship类添加构造/析构函数管理内存

通过构造函数初始化指针,析构函数释放内存,避免内存泄漏:

class Ship{
    private:
        string name;
        string yearMade;
        Address *address;
    public:
        // 构造函数:初始化address指针
        Ship() {
            address = new Address();
        }
        // 析构函数:释放address占用的内存
        ~Ship() {
            delete address;
        }
        // 保留原有的print和read方法
};

方案二:将指针替换为对象成员(更简洁)

如果不需要动态分配内存,直接用Address对象作为Ship的成员,既符合聚合关系的设计,又彻底避免指针问题:

class Ship{
    private:
        string name;
        string yearMade;
        Address address; // 替换为对象而非指针
    public:
        void print(){
            cout<<"Ship Name: "<< name <<endl;
            cout<<"Year Built: "<< yearMade <<endl;
            cout<<"Registered at: "<<endl<<address.getRegistrar()<<", "<<address.getCountry()<<endl;
        }
        void read(){
            string r, c;
            cout<<"<<< Enter the information of the ship >>>"<<endl<<endl;
            cout<<"Ship Name: ";
            getline(cin, name);
            cout<<"Year Built: ";
            getline(cin, yearMade);
            cout<<"The address the ship was registered:"<<endl;
            cout<<"Registrar Office: ";
            getline(cin, r);
            cout<<"Country: ";
            getline(cin, c);
            address.set(r, c); // 直接调用对象的set方法
        }
};

2. 额外优化:修复动态数组内存泄漏

main函数中用new Ship[100]创建的数组,最后需要手动释放内存:

int main() {
    Ship *ship = new Ship[100];
    // 原循环逻辑...
    
    delete[] ship; // 释放动态数组内存
    return 0;
}

完整修复后的代码(方案二版本)

#include <iostream>
#include <string>
using namespace std;

class Address{
    private:
        string registrar;
        string country;
    public:
        void set(string r, string c){
            registrar = r;
            country = c;
        }
        string getRegistrar(){
            return registrar;
        }
        string getCountry(){
            return country;
        }
};

class Ship{
    private:
        string name;
        string yearMade;
        Address address;
    public:
        void print(){
            cout<<"Ship Name: "<< name <<endl;
            cout<<"Year Built: "<< yearMade <<endl;
            cout<<"Registered at: "<<endl<<address.getRegistrar()<<", "<<address.getCountry()<<endl;
        }
        void read(){
            string r, c;
            cout<<"<<< Enter the information of the ship >>>"<<endl<<endl;
            cout<<"Ship Name: ";
            getline(cin, name);
            cout<<"Year Built: ";
            getline(cin, yearMade);
            cout<<"The address the ship was registered:"<<endl;
            cout<<"Registrar Office: ";
            getline(cin, r);
            cout<<"Country: ";
            getline(cin, c);
            address.set(r, c);
        }
};

int main() {
    
    Ship *ship = new Ship[100];
    int option=0, total=0;
    
    while(option != 3){
        cout<<"======== MENU ========"<<endl;
        cout<<"1. Add a ship"<<endl;
        cout<<"2. Display ships"<<endl;
        cout<<"3. Exit."<<endl<<endl;
        cout<<"Choose an operation => ";
        cin >> option;
        cin.ignore();
        if(option == 1){
            ship[total].read();
            total++;
        }else if(option == 2){
            cout<<"<<< Inventory of ships >>>"<<endl<<endl;
            cout<<"Total ship: "<<total<<endl<<endl;
            cout<<"==== Ship List ===="<<endl<<endl;
            for(int i=0; i<total; i++){
                ship[i].print();
                cout<<endl; // 增加换行,优化输出可读性
            }
        }
    }
    
    delete[] ship;
    return 0;
}

内容的提问来源于stack exchange,提问作者Khairul Hakimi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 02:07:02