korbs korbs - 24 days ago 5
C++ Question

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++;

}



}

Answer

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;
}