프로그램에 대하여

조회수 609회
#include <iostream>
#include <cstring>
#define _CRT_SECURE_NO_WARNINGS

using std::cout;
using std::cin;
using std::endl;

class Info
{
private:
    int accountID;
    char* name; /*동적할당으로 구현*/
    int total;
public:
    Info(int id, char * nm, int tot)
        :accountID(id), total(tot)
    {
        name = new char[strlen(nm) + 1];
        strcpy_s(name, strlen(nm) + 1, nm);
    }
    int ID()
    {
        return accountID;
    }
    void print()
    {
        cout << "계좌ID: " << accountID << endl;
        cout << "이 름: " << name << endl;
        cout << "잔 액: " << total << endl;
    }
    void withdraw(int money)
    {
        total -= money;
    }
    void deposit(int money)
    {
        total += money;
    }
    ~Info()
    {
        delete []name;
    }
};

enum selectnum
{
    Makingnum = 1,
    Depositnum,
    Withdrawnum,
    PrintInfonum,
    Exitnum
};

int num = 0;
Info * i[10]; 
int deposit_amount;
int withdraw_amount;

void ask_Deposit();

void ask_Withdraw();

int Menu() {
    int select;
    cout << "-----Menu------" << endl;
    cout << "1.계좌개설" << endl;
    cout << "2.입금" << endl;
    cout << "3.출금" << endl;
    cout << "4.계좌정보 전체 출력" << endl;
    cout << "5.프로그램 종료" << endl;
    cout << "선택:  ";
    cin >> select;
    return select;
}

void Making() {
    int id;
    char na[20];
    int to;
    cout << "[계좌개설]" << endl;
    cout << "계좌ID: ";
    cin >> id;
    cout << "이 름: ";
    cin >> na;
    cout << "입금액: ";
    cin >> to;
    i[num] = new Info(id, na, to);
    /*main함수에서 Making 함수를 불러온 뒤에 num++해줄것*/
}

void Deposit() {
    int id;
    cout << "[입금]" << endl;
    cout << "계좌ID: ";
    cin >> id;
    for (int n = 0; n < 10; n++)
    {
        if (i[n]->ID()==id)
        {
            cout << "입금액: ";
            cin >> deposit_amount;
            if (deposit_amount > 0)
            {
                i[n]->deposit(deposit_amount);
                cout << "입금완료";
                return;
            }
            else {
                cout << "입금액은 0보다 커야 됩니다." << endl;
            }
        }
    }
    cout << "개설된 계좌ID가 없습니다." << endl;
}

void Withdraw() {
    int id;
    cout << "[출금]" << endl;
    cout << "계좌ID: ";
    cin >> id;
    for (int n = 0; n < 10; n++)
    {
        if (id == i[n]->ID())
        {
            cout << "출금액: ";
            cin >> withdraw_amount;
            if (withdraw_amount > 0)
            {
                i[n]->withdraw(withdraw_amount);
                cout << "출금완료";
                return;
            }
            else {
                cout << "입금액은 0보다 커야 됩니다." << endl;
            }
        }
    }
    cout << "개설된 계좌ID가 없습니다." << endl;
}

void PrintInfo() {
    for (int n = 0; n < 10; n++)
    {
        if (i[n]->ID()!=0)   /*계좌가 등록되어있으면*/
        {
            i[n]->print();
        }
    }
}

int main(void) {

    while (1)
    {
        int select = Menu();
        switch (select) 
        {
        case Makingnum:
            Making();
            num++;
            break;
        case Depositnum:
            Deposit();
            break;
        case Withdrawnum:
            Withdraw();
            break;
        case PrintInfonum:
            PrintInfo();
            break;
        case Exitnum:
            for (int n = 0; n < num; n++)
                delete i[n];
            return 0;
        default:
            cout << "Illegal selection.." << endl;
        }
    }

    return 0;
}

이런 프로그램을 하나 작성해보았는데요 프로그램을 돌리다가보면 입금과 출금을 할 때 계좌 ID가 틀렸을 경우에 프로그램이 종료가 되버리고 4번인 계좌 정보출력을 하게되어도 프로그램이 종료되는 문제점을 발견했습니다. 제가 생각한 바로는 menu()에서 5를 입력하지 않는 이상 while문을 계속 돌게 되므로 프로그램이 종료되지 않아야 되는데 왜 종료가 되는 걸까요?

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    문제는 Info * i[10];nullptr로 초기화되어 있는데 i[n]->ID()로 접근하기 때문에 런타임 에러가 발생하는 것입니다.

    아래와 같이 바꾸세요.

    void Deposit() {
        int id;
        cout << "[입금]" << endl;
        cout << "계좌ID: ";
        cin >> id;
        for (int n = 0; n < 10; n++)
        {
            if (i[n]) {    // 추가됨1
                if (i[n]->ID() == id)
                {
                    cout << "입금액: ";
                    cin >> deposit_amount;
                    if (deposit_amount > 0)
                    {
                        i[n]->deposit(deposit_amount);
                        cout << "입금완료";
                        return;
                    }
                    else {
                        cout << "입금액은 0보다 커야 됩니다." << endl;
                    }
                }
            }
        }
        cout << "개설된 계좌ID가 없습니다." << endl;
    }
    
    void Withdraw() {
        int id;
        cout << "[출금]" << endl;
        cout << "계좌ID: ";
        cin >> id;
        for (int n = 0; n < 10; n++)
        {
            if (i[n]) { //추가됨2
                if (id == i[n]->ID())
                {
                    cout << "출금액: ";
                    cin >> withdraw_amount;
                    if (withdraw_amount > 0)
                    {
                        i[n]->withdraw(withdraw_amount);
                        cout << "출금완료";
                        return;
                    }
                    else {
                        cout << "입금액은 0보다 커야 됩니다." << endl;
                    }
                }
            }
        }
        cout << "개설된 계좌ID가 없습니다." << endl;
    }
    
    void PrintInfo() {
        for (int n = 0; n < 10; n++)
        {
            if (i[n]) { //추가됨3
                if (i[n]->ID() != 0)   /*계좌가 등록되어있으면*/
                {
                    i[n]->print();
                }
            }
        }
    }
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 감사합니다! 덕분에 해결됐습니다. 널포인터일 경우에는 접근이 불가한건가요? 임성환 2023.10.20 11:33
    • 포인터 변수는 언제나 메모리 할당 후 사용해야합니다. 널 포인터라는 것은 할당된 메모리가 없다는 뜻입니다. 할당된 메모리도 없으니 메모리 내부로 접근할수 없는 것은 당연하고, 접근 할수없는데 접근하기 때문에 실행시간 에러가 발생하는 것입니다. 알 수 없는 사용자 2023.10.23 17:01

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)