Search code examples
c++arraysvisual-studioclassaccess-violation

Access Violation C++ visual studio Classes


I am getting a: "Exception thrown at 0x00E8316C in ConsoleApplication18.exe: 0xC0000005: Access violation writing location 0xCDCDCDD1." When I run my code, this is all of it and the error breaks where I marked with a comment. Thank you for your time!

#include "iostream"
using namespace std;


class Transaction
{
public:
    int USERID;
    int Amount;
    virtual void Report()   //modify for each transaction type
    {

    }

    virtual void Perform()  //modify for each transaction type
    {

    }

};


class Transfer : public Transaction
{
public:
    int transID;   // id of the user to tranfer with
    int transType; // type of transition; to or fro

    void Perform()
    {
        cout << "\n" << "Transfer" << "\n\n";
        cout << "Enter the id of the user to tranfer with: ";
        cin >> transID;
        cout << "\n" << "Transfer type:" << "\n" << "1: To   2: Fro" << "\n";
        cin >> transType;
        if (transType == 2)
        {
            int temp = transID;
            transID = USERID;
            USERID = temp;
        }
        cout << "\n" << "Enter the amount you wish to withdraw: ";
        cin >> Amount;

    }

    void Report()
    {
        cout << "\n\n" << "Transfer of " << Amount << "$ from user: #" << USERID << " to the user: #" << transID;
    }

};


class Withdraw : public Transaction
{
public:

    void Perform()
    {
        cout << "\n" << "Withdraw" << "\n\n";
        cout << "Enter the amount you wish to withdraw: ";
        cin >> Amount;

    }
    void Report()
    {
        cout << "\n\n" << "Withdrawl of: " << Amount << "$";
    }

};

class Deposit : public Transaction
{
public:

    void Perform()
    {
        cout << "\n" << "Deposit" << "\n";
        cout << "Enter the amount you wish to deposit: ";
        cin >> Amount;
    }
    void Report()
    {
        cout << "\n\n" << "Deposit of: " << Amount << "$";
    }

};




class User
{
public:
    int ID;
    int numTrans;
    Transaction* t[100];
    int TYPE;

    User()
    {
        numTrans = 0;
    }

    void AddWithdraw()
    {
        t[numTrans] = new Withdraw;
        numTrans++;
    }

    void AddDeposit()
    {
        t[numTrans] = new Deposit;
        numTrans++;
    }

    void AddTransfer()
    {
        t[numTrans] = new Transfer;
        numTrans++;
    }

};


void main()
{
    User*u[100];
    int id;
    int type;
    int counter;

    counter = 0;

    for (int i = 0; i <= 100; i++)
    {
        u[i] = new User;
    }

    while (true)
    {
        type = 0;

        cout << "\nPlease enter your ID: ";
        cin >> id;

        cout << "\n" << "Which transaction would you like to perform" << "\n" << "1: Withdraw" << "\n" << "2: Deposit" << "\n" << "3: Transfer" << "\n";
        cin >> type;

        if (type != 1 && type != 2 && type != 3)
        {
            type = 1;
        }

        for (int i = 0; i <= counter; i++)
        {
            if (u[i]->ID == id || i == counter)
            {

                if (i == counter)// Add the type of transaction to the transaction array
                {
                    if (type == 1) { u[i]->AddWithdraw(); }
                    if (type == 2) { u[i]->AddDeposit(); }
                    if (type == 3) { u[i]->AddTransfer(); }

                }

                u[i]->t[u[i]->numTrans]->USERID = id; //BREAKS HERE
                u[i]->t[u[i]->numTrans]->Perform();

                for (int b = 0; b <= u[i]->numTrans; b++)
                {

                    u[i]->t[b]->Report();
                }
                break;
            }
        }

        // Report all of the previous transactions
        counter++;

    }



}

Solution

  • There are a lot of errors in your code.

    • Transaction is missing a virtual destructor.

    • you are not doing any bounds checking when filling your arrays.

    • your loops are using <= when they need to use < instead.

    • main loop is going out of bounds when accessing the u[i]->t[] array.

    • you are not assigning the ID field of each allocated User, so you can't find users by their id.

    • you are leaking memory since you never free any of the Transaction or User objects.

    Try something more like this instead:

    #include <iostream>
    
    using namespace std;
    
    class Transaction
    {
    public:
        int USERID;
        int Amount;
    
        virtual Transaction() {}
    
        virtual void Report() = 0;
        virtual void Perform() = 0;
    };
    
    class Transfer : public Transaction
    {
    public:
        int transID;   // id of the user to tranfer with
        int transType; // type of transition; to or fro
    
        void Perform()
        {
            cout << "\n" << "Transfer" << "\n\n";
            cout << "Enter the id of the user to tranfer with: ";
            cin >> transID;
            cout << "\n" << "Transfer type:" << "\n" << "1: To   2: Fro" << "\n";
            cin >> transType;
            if (transType == 2)
            {
                int temp = transID;
                transID = USERID;
                USERID = temp;
            }
            cout << "\n" << "Enter the amount you wish to withdraw: ";
            cin >> Amount;    
        }
    
        void Report()
        {
            cout << "\n\n" << "Transfer of " << Amount << "$ from user: #" << USERID << " to the user: #" << transID;
        }    
    };
    
    class Withdraw : public Transaction
    {
    public:    
        void Perform()
        {
            cout << "\n" << "Withdraw" << "\n\n";
            cout << "Enter the amount you wish to withdraw: ";
            cin >> Amount;
    
        }
    
        void Report()
        {
            cout << "\n\n" << "Withdrawl of: " << Amount << "$";
        }    
    };
    
    class Deposit : public Transaction
    {
    public:    
        void Perform()
        {
            cout << "\n" << "Deposit" << "\n";
            cout << "Enter the amount you wish to deposit: ";
            cin >> Amount;
        }
    
        void Report()
        {
            cout << "\n\n" << "Deposit of: " << Amount << "$";
        }    
    };
    
    class User
    {
    public:
        int ID;
        int numTrans;
        Transaction* trans[100];
        int TYPE;
    
        User()
        {
            numTrans = 0;
        }
    
        ~User()
        {
            for (int i = 0; i < numTrans; ++i)
                delete trans[i];
        }
    
        Transaction* AddTransaction(int type)
        {
            if (numTrans == 100)
                return NULL;
    
            Transaction *t;
    
            switch (type)
            {
                case 1:
                    t = new Withdraw;
                    break;
    
                case 2:
                    t = new Deposit;
                    break;
    
                case 3:
                    t = new Transfer;
                    break;
    
                default:
                    return NULL;
            }
    
            trans[numTrans] = t;
            numTrans++;
    
            return t;
        }
    
        Transaction* AddWithdraw()
        {
            return AddTransaction(1);
        }
    
        Transaction* AddDeposit()
        {
            return AddTransaction(2);
        }
    
        Transaction *AddTransfer()
        {
            return AddTransaction(3);
        }
    };
    
    void main()
    {
        User* users[100];
        int numUsers = 0;
        int id;
        int type;
    
        for (int i = 0; i < 100; ++i)
        {
            users[i] = new User;
            users[i]->ID = i+1;
            ++numUsers;
        }
    
        while (true)
        {
            cout << "\nPlease enter your ID: ";
            cin >> id;
    
            User *user = NULL;
            for (int i = 0; i < numUsers; ++i)
            {
                if (users[i]->ID == id)
                {
                    user = users[i];
                    break;
                }
            }
    
            if (!user)
            {
                cout << "Invalid id!" << "\n";
                continue;
            }
    
            type = 0;
    
            do
            {
                cout << "\n" << "Which transaction would you like to perform" << "\n" << "1: Withdraw" << "\n" << "2: Deposit" << "\n" << "3: Transfer" << "\n" << "4: Quit" << "\n";
                cin >> type;
    
                if ((type >= 1) && (type <= 4))
                    break;
    
                cout << "Invalid selection!" << "\n";
            }
            while (true);
    
            if (type == 4)
                break;
    
            // Add the type of transaction to the transaction array
            Transaction *trans = user->AddTransaction(type);
            if (!trans)
            {
                cout << "Too many transactions for this id!" << "\n";
                continue;
            }
    
            trans->USERID = id;
            trans->Perform();
    
            for (int b = 0; b < user->numTrans; ++b)
                 user->trans[b]->Report();
        }
    
        for (int i = 0; i < numUsers; ++i)
            delete users[i];
    
        return 0;
    }