0

I am trying to write a program that will read the contents of a .csv file into an array then print the results to the screen (part of a larger project) when the function getNumberOfRooms() is called an exception is thrown when it tries to return the value of the numberOfRooms variable, a private member within the class. Has anyone had a problem like this before or helped someone with this sort of problem? If so how did you solve it?

Thanks in advance,

Full source code available here: https://bitbucket.org/skutov/micropuzzle/

The exception that is thrown when getNumberOfRooms() is called:

Unhandled exception at 0x01354aa6 in MICROPUZZLE.exe: 0xC0000005: Access violation
reading location 0xccccccd0.

These are the functions in question (all of the time the variable is referenced in the class)

ClassMap::ClassMap ()
{
    numberOfRooms = 0;

    // Get number of rooms in map.csv

    /* Find number of entries in map.csv file */

        numberOfRooms = number_of_lines;

    // allocate memory for rooms array

    /* loading data from file into array */
    }
}    

// self explanitory
int ClassMap::getNumberOfRooms()
{
    // Exception occurs on this line when accessing the variable
    return numberOfRooms;
}

int ClassMap::printRoomDescriptions ()
{
    for(int j = this->getNumberOfRooms(); j > 0; j--)
    {
        cout << roomArray[j].getDescription();
    }
    return 0;
}

Here is the class header:

class ClassMap
{
private:
    int currentLocation;
    int numberOfRooms;
    // pointer to array initialised in constructor
    ClassRoom *roomArray;

public:
    // Constructors and Destructors
    ClassMap();
    ~ClassMap();

    // Print description, events and directions for current room
    std::string getCurrentRoom();

    // Change currentLocation to neighbour of current room if possible
    int moveRoom(char direction);


    // self explanitory
    int getNumberOfRooms();

    // dump room descriptions to command line (debugging)
    int printRoomDescriptions();

};

Here is the constructor for ClassMap which also initializes roomArray:

ClassMap::ClassMap ()
{
    numberOfRooms = 0;

    // Get number of rooms in map.csv

        unsigned int number_of_lines = 0;
        FILE *infile = fopen("map.csv", "r");
        int ch;

        while (EOF != (ch=getc(infile)))
            if ('\n' == ch)
                ++number_of_lines;
        fclose(infile);
        numberOfRooms = number_of_lines;




    // allocate memory for rooms array
    roomArray = new ClassRoom[numberOfRooms+1];

    // set starting room
    int currentLocation = 1;

    // load that shit up
    {
        // Holders for values read from file
        int newRoomID = 0;
        char newRoomDescription[79] = "";
        int newRoomNorthNeighbour = 0;
        int newRoomEastNeighbour = 0;
        int newRoomSouthNeighbour = 0;
        int newRoomWestNeighbour = 0;

        // used for iterations
        int i = 0;

        // File stream for map.csv
        std::ifstream mapFile;

        // Crack that shit open
        mapFile.open ("map.csv");

        // Line buffer for parsing
        std::string line;


        // For each line in the map.csv file read in the values into variables declared above then run initialise function for each room to store values into array
        while (std::getline(mapFile, line))
        {
            // re-init parameters

            newRoomID = 0;
            newRoomNorthNeighbour = 0;
            newRoomEastNeighbour = 0;
            newRoomSouthNeighbour = 0;
            newRoomWestNeighbour = 0;
            for(i = 0;i<79;i++)
            {
                newRoomDescription[i] = ' ';
            }


            int parameter = 0;

            int paraStart = 0;
            int paraEnd = 0;

            std::string buffer;
            std::istringstream iss(line);

            for(parameter = 0; parameter <= 5; parameter++)
            {
                // Empty buffer from last iteration
                buffer.clear();

                // Find end of current parameter
                paraEnd = line.find(',',paraStart+1);

                switch (parameter)
                {
                case 0:
                    buffer = line.substr((paraStart),(paraEnd-paraStart));
                    newRoomID = atoi(buffer.c_str());
                    break;
                case 1:
                    buffer = line.substr((paraStart+2),(line.find("\"",paraStart+2)-(paraStart+2)));
                    for(i = 0;i<(buffer.length());i++)
                    {
                        newRoomDescription[i] = buffer.c_str()[i];
                    }
                    //newRoomDescription
                    break;
                case 2:
                    buffer = line.substr((paraStart+1),(paraEnd-paraStart));
                    newRoomNorthNeighbour = atoi(buffer.c_str());
                    break;
                case 3:
                    buffer = line.substr((paraStart+1),(paraEnd-paraStart));
                    newRoomEastNeighbour = atoi(buffer.c_str());
                    break;
                case 4:
                    buffer = line.substr((paraStart+1),(paraEnd-paraStart));
                    newRoomSouthNeighbour = atoi(buffer.c_str());
                    break;
                case 5:
                    buffer = line.substr((paraStart+1),(paraEnd-paraStart));
                    newRoomWestNeighbour = atoi(buffer.c_str());
                    break;
                } // switch

                // Cycle paraEnd to paraStart
                paraStart = paraEnd;

            } // for parameters loop

            // Init next room with data
            new (&roomArray[newRoomID]) ClassRoom(  newRoomNorthNeighbour,
                newRoomEastNeighbour,
                newRoomSouthNeighbour,
                newRoomWestNeighbour,
                newRoomDescription);

        } // while !EOF
        // Close the file because we're a good little program and we don't need that shit no more
        mapFile.close();
    }
}
Skutov
  • 1
  • 1

2 Answers2

2

The key to this issue is:

Access violation reading location 0xccccccd0

0xcccccccc is a special value used in debug mode to denote an unitialised pointer. (See How to end up with a pointer to 0xCCCCCCCC ) It is set in debug mode to cause this kind of crash - it means the pointer you are using is not yet setup. Once you set up the pointer correctly the error will go away. (The slight difference from 0xcccccccc is the offset of the member you're trying to access inside that object.)

ADDED:

This is your error:

ClassRoom* roomArray = static_cast<ClassRoom*>( ::operator new ( sizeof ClassRoom * numberOfRooms ) );

This creates a local roomArray variable, and hides the member variable. What you really want is:

roomArray = static_cast<ClassRoom*>( ::operator new ( sizeof ClassRoom * numberOfRooms ) );

Or better yet:

roomArray = new ClassRoom[numberOfRooms];
Community
  • 1
  • 1
Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
  • Thanks for the advice, having taken your changes into account it hasn't made a difference to the program, except for making it look a bit neater. I've edited the changes into the original question. Just to make sure things are clear, the variable numberOfRooms is used fine in this context, it is the get function that causes the error. – Skutov Apr 08 '14 at 12:32
  • The code does look better, but its still litttered with oddities, and potential errors. (Can't tell if they're actuall errors as we dont have all the code.) I think you really need to create a better reduced example of your code to show us if you want further help. See http://www.sscce.org/ for what is expected. – Michael Anderson Apr 09 '14 at 00:18
1

I guess the problem is your for loop for(int j = this->getNumberOfRooms(); j > 0; j--). It should look like this: for(int j = this->getNumberOfRooms()-1; j >= 0; j--). The last accessible index in an arry with N entries is N-1. On the other hand, the first index is 0.

maddin45
  • 737
  • 7
  • 17
  • Thanks for the pointer, not quite where the problem lies but that did highlight another issue with the way I have written my .csv files. Saved a potential headache there. – Skutov Apr 08 '14 at 12:33