-4

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

    }



}
halfer
  • 19,824
  • 17
  • 99
  • 186
korbs
  • 11
  • 3
  • 5
    The `u` array in `main` has 100 elements. You write 101 elements. – Some programmer dude Nov 11 '16 at 17:14
  • 2
    Please [edit] your question to provide a [mcve]. – Baum mit Augen Nov 11 '16 at 17:15
  • 1
    In addition, your base class `Transaction` is missing a virtual destructor. – PaulMcKenzie Nov 11 '16 at 17:15
  • I changed the loop in main to have 100 elements and I added a destructor to my Transaction class, still gives me this violation. : / Thank you for the fast response tho! – korbs Nov 11 '16 at 17:36
  • 1
    Also in `main()`, `counter` is being misused when looping through `u[]`. So you can end up accessing memory that is out of bounds of `u[]`. Your loops should be using `<` instead of `<=`. And using `u[i]->numTrans` as-is when accessing `u[i]->t[]` will always be out of bounds of `t[]`. – Remy Lebeau Nov 11 '16 at 17:36
  • counter is initialized and set to 0 before the while(true) and I use <= to count up to the counter's slot of the array u[] – korbs Nov 11 '16 at 17:40
  • 0xCDCDCDD1 --> looks like you are using a pointer that is uninitialized heap memory. http://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations – drescherjm Nov 11 '16 at 17:44
  • Maybe you should initialize `t` in your constructor. With that said it looks like the problem is mainly due to using `<=` in all of your for loops when you should be using `<` – drescherjm Nov 11 '16 at 17:46
  • Thank you guys for your fast responses! I'm salvaging the code now – korbs Nov 11 '16 at 17:51
  • I ended up deleting all of the u[ i ]->t[ ] 's in my code and using functions within u's class to access t[ ], I don't understand what was wrong with writing this... but it's no longer giving me an error, so thank you! – korbs Nov 11 '16 at 18:08

1 Answers1

1

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;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • @drescherjm: fixed – Remy Lebeau Nov 11 '16 at 18:13
  • Thank you Remy! I will look over this, is there a simple reason why: u[i]->t[] goes out of bonds? – korbs Nov 11 '16 at 18:16
  • @korbs: array indexes are 0-based, so the valid indexes for `t[]` are `0 .. (numTrans-1)`, inclusive. Using `numTrans` as-is goes +1 past the end of the array into surrounding memory. Your loops exhibit the same error when they use `<=` instead of `<`. – Remy Lebeau Nov 11 '16 at 18:38