I keep getting access violations even though I made sure to make all my methods and functions const! Driving me insane.
When I add a player then try to display all players the program tries to read my privates then gets violated.
(Still lots of bugs in it elsewhere, but this is the only one I don't know how to fix)
Here is link to my program Click Here

/*
main.cpp
    #define _CRT_SECURE_NO_WARNINGS
    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>

    #include "sport.h"

    #include <iostream>
    using std::cout;

    int main()
    {
        _CRT_SECURE_NO_WARNINGS

            _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

        Sport InterGalacticHoops;

              InterGalacticHoops.DisplayMenu() ;

        system("pause");
        return 0;
    }

player.cpp

    #ifdef _MSC_VER
    #define _CRT_SECURE_NO_WARNINGS
    #endif
    #include "player.h"

    #include <iostream>
    using std::cout;
    using std::endl;

    #include <cstring>
    using std::strcpy;

    //won't compile without this for static public variable
    int Player::m_numPlayers = 0;

    //Getters
    char* Player::GetName() const {return m_name;}
    int Player::GetGrade() const {return m_grade;}
    double Player::GetGPA() const {return m_gpa;}

    Player::Player(const char * name, int grade, double gpa)
    {
        //Passed in name is now player's true earth name

        //Allocates enough memory for m_name to fit name in it; + 1 for null
        m_name = new char[strlen(name) + 1];
        strcpy( m_name, name ) ;

        m_grade = grade;

        m_gpa = gpa;

        //public static that increments number of players.
        m_numPlayers++;

    }

    Player::~Player()
    {
        delete[] m_name;
    }


    //Recieves char* name to be searched, returns true if found
    bool Player::Search(const char * playa) const
    {

        bool foundPlayer = false;

        //If the passed in player name c string matches this player's member name return true.
        if ( strcmp(playa, m_name) == 0 )
            foundPlayer = true;



        return foundPlayer;

    }
       void Player::Display() const
    {
        cout << "\nPlayer Name:  " << "GetName()" << 
            "\nGrade:        " << "GetGrade()" << "\nG.P.A.        " << "GetGPA()" << endl;
    }
    //PROBLEM AREA RIGHT HERE


player.h


    #ifndef PLAYER_H
    #define PLAYER_H
    class Player
    {
    public:

        Player(const char * name, int grade, double gpa) ;

        ~Player() ;

        char* GetName() const;
        int GetGrade() const;
        double GetGPA() const;

        bool Search(const char*) const;

        void Display() const;

        //Keeps track of player objects
        static int m_numPlayers;



    private:
        char* m_name;
        int m_grade;
        double m_gpa;

    };
    #endif


sport.cpp
    #ifdef _MSC_VER
    #define _CRT_SECURE_NO_WARNINGS
    #endif
    #include "sport.h"

    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;

    Sport::Sport()
        {
          length = 0;
        }

        Sport::~Sport()
        {
          //delete [] array;//for length toto
        }


    void Sport::PromptUser()
    {
        cout << "\n\n\nA - Add a Player" <<
            "\nS - Search For / Display a Player" <<
            "\nD - Display all Players" <<
            "\nC - Display Current Count of Players" <<
            "\nE - Exit" << endl;
    }



    void Sport::Add()
    {
        const int BUFFER = 200;

        char * usrName = nullptr;
        char tempName[BUFFER] ;
        int usrGrade;
        double usrGPA;

        ///GET USER INPUT, INSTANTIATE fresh PLAYER
        cout << "\nEnter Player Name: " << endl;
        cin >> tempName;

        usrName = new char[strlen(tempName)+1] ;
        strcpy(usrName, tempName) ;

        cout << "\nEnter Player Grade: ";
        cin >> usrGrade;

        cout << "\nEnter Player GPA: ";
        cin >> usrGPA;

        //Take inputs and make Player object with them.
        Player fresh(usrName, usrGrade, usrGPA) ;

        delete usrName;
        ///////////////////////////////////////////



        //Now, copy array's contents to temp array of pointers
        Player** temp = nullptr; 
                     //*
        temp = new Player*[length] ;

        for (int j(0); j < length; ++j) 
        {
            temp[j] = array[j] ;
        } 
        /////////////////////////////////////////////////////////



        //Delete old array that is now represented with temp
        for (int p(0); p < length; ++p) 
        {
            delete [] array[p] ;
        }  
    //  delete [] array;
        ////////////////////////////////////////////////////



        //Allocate and fill new array, then append new Player pointer to the array
        array = new Player*[length + 1];
        for (int j(0); j < length; ++j) 
        {
            array[j] = temp[j] ;
        }                   //new?
        array[length+1] =      &fresh; //arrays pointer player pointer is now fresh
        ///////////////////////////////////////////////////////////////////////////

        //Delete temp
        for (int p(0); p < length; ++p) 
        {
            delete [] temp[p] ;
        }  
        delete [] temp;


        //Increments Pointer array of Player pointers
        length++;
    }

    void Sport::List()
    {
        for(int i(0); i < length; i++)
        {
            array[i]->Display() ;
        }

    }

    void Sport::Search() const
    {
        bool foundPlayer = false;

        const int BUFFER = 256;

        char * usrName = "j";
        cout << "\nEnter Player Name: ";
        cin.getline (usrName,BUFFER);

        //Brute force search since Miles' team only needs 10 or so players.
        for(int i(0); i < length && !foundPlayer; i++)
        {
            if ( array[i]->Search(usrName) )
            {
                array[i]->Display() ;
                foundPlayer = true;
            }
        }

        if (!foundPlayer)
            cout << "\nSorry. This player could not be located in all of space time." << endl;
    }


    void Sport::DisplayCount()
    {
        cout << "\nNumber of Players:  " << array[0]->m_numPlayers << endl;
    }


    void Sport::DisplayMenu()
    {
        cout << "\nWelcome Danny Miles, assemble your team roster from all of space time " 
            <<  "to defend the Milky Way's Title from Zorbak!\n"
            << "\nThis. \nIs. \n\n      S P A C E   J A M   II" ;
        bool done = false;
        char str[77] = "a";
        do
        {
            PromptUser() ;
            cin >> str;
    while (!isalpha(str[0]))
    {
    cout << "You have entered an invalid input, please input a letter: ";
    cin >> str;
    }
    char input = toupper(str[0]) ;


            enum cases { ADD, SEARCH, DISPLAY, COUNT, EXIT} ;
            cases choice = EXIT;

            if      ( input == 'a' || input == 'A' )
                choice = ADD;
            else if ( input == 's' || input == 'S' )
                choice = SEARCH;
            else if ( input == 'd' || input == 'D' )
                choice = DISPLAY;
            else if ( input == 'c' || input == 'C' )
                choice = COUNT;
            else if ( input == 'e' || input == 'E' )
                choice = EXIT;


            switch ( choice )
            {
            case ADD:
                   Add() ;
                break;

            case SEARCH:
                   Search() ;
                break;

                case DISPLAY:
                   List() ;
                break;

                case COUNT:
                   DisplayCount() ;
                break;

                case EXIT:
                   done = true;
                break;

            default:
                cout << "\n\nThis is no time for games! (you know what I mean)";
            }

        }while(!done);

    }
sport.h


    #ifndef SPORT_H
    #define SPORT_H

    #include "player.h"

    class Sport
    {
    public:
        Sport() ;
        ~Sport() ;
        void DisplayMenu() ;
        void Add() ;
        void List() ;
        void Search() const;
        void DisplayCount() ;


    private:
        void PromptUser();
        Player**  array;
        int length;
    };
    #endif 





*/

Recommended Answers

All 2 Replies

You are trashing our memory in your Sport::Add() function. You are adding a local variable to an array of pointers on line 222 which I believe is causing your issues. Have you ever thought about using vectors instead of arrays so you don't have to worry about the memory management. The same thing goes with your \Player class and the use of c-strings. If you convert your Player class to use std::string and your Sport class to use a vector, Add() would look like the following:

void Sport::Add()
{

    std::string usrName;
    int usrGrade;
    double usrGPA;

    ///GET USER INPUT, INSTANTIATE fresh PLAYER
    cout << "\nEnter Player Name: " << endl;
    cin >> usrName;

    cout << "\nEnter Player Grade: ";
    cin >> usrGrade;

    cout << "\nEnter Player GPA: ";
    cin >> usrGPA;

    // have a vector called players defined as std::vector<Player> players;
    players.push_back(Player(usrName, usrGrade, usrGPA))
}

Your are deleting memory that is in use and you are mixing heap and stack memory and trying to delete stack memory, all in Sport::add.

You are using dynamic arrays of pointers so

Line 194 - 201: Allocate a new array of pointers (temp) copy pointers from array to temp

resulting in the arrays temp and array containing the same pointers but

Line 206 - 211: Delete the data pointed to by the pointers in array, delete array. You delete the data pointed to by the pointers in array but this is also the data pointed to by the pointers in temp. You have deleted data you are not yet finished with. You only need to delete array not what the pointers in array are pointing to.

then

Line 216 - 221: Copy the now invalid pointers in temp back to a newly allocated array

Line 222: Store a pointer to fresh which is on the stack and won't exist past the end of the method in array where later it will be treated as if it was on the heap and deleted.

and finally

Line 225 - 230: Delete the data pointed to by the pointers in temp this has already been deleted at line 206 - 211 so is a double delete.

At line 206-211 you delete data you have not yet finished using
At line 222 you store a stack pointer that will become invalid in an array you are assuming contains heap pointers
At line 225 - 230 you delete memory that has already been deleted

These are all causes of undefined behaviour and probably causing your crash.

The pseudo code for adding an extra item to an array stored like this is

Allocte new item on heap (use new)
Allocate new array of pointers one longer than the old one (stored in temp)
Copy contents of array to temp (leaving 1 unitialised value at end)
Store value of new item in last entry of temp (the unitialised one)
Delete array (but not what the pointers it contains point to)
Copy value of temp to array (literally `temp = array` no need to delete anything)

A for loop is at most only required for the third line of this code.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.