Search code examples
c++visual-studioifstream

C++ Access Violation writing Location 0x00B0A654


So I'm developing tile engine for a game built-in C++. as part of this, I want to store and load tiles from a .txt file saved in the game's directory.

this code saves a level

void LevelManager::SaveToFile(char * FileName)
{
    ofstream File(FileName);
    File.clear();
    for (unsigned y = 0; y < 300; y++) {
        for (unsigned x = 0; x < 300; x++) {

            File << TileGrid[x][y].PhysicsNumber << " ";
            File << TileGrid[x][y].GT.TopLeft << " ";
            File << TileGrid[x][y].GT.TopRight << " ";
            File << TileGrid[x][y].GT.BottomLeft << " ";
            File << TileGrid[x][y].GT.BottomRight << " ";
        }
        File <<  "\n";
    }
    File.close();
}

and then the following code reads the file

void LevelManager::LoadFromFile(char * FileName)
{
    ifstream infile;
    int y = 0;
    int x = 0;
    int counter = 1;
    infile.open(FileName);
    while (y < 300) {
        char Current = 0;
        infile.read(&Current, 1);
        if (Current == 10) {
            y++; 
            x = 0;
        }
        else if (Current == 32) {
            counter++;
            if (counter > 5) counter = 1;
            x++;
        }
        else if (counter == 1) {
            TileGrid[x][y].PhysicsNumber = (TileGrid[x][y].PhysicsNumber * 10) + Current - 48;
        }
        else if (counter == 2) {
                TileGrid[x][y].GT.TopLeft = (TileGrid[x][y].GT.TopLeft * 10) + Current - 48;
        }
        else if (counter == 3) {
            TileGrid[x][y].GT.TopRight = (TileGrid[x][y].GT.TopRight * 10) + Current - 48;
        }
        else if (counter == 4) {
            TileGrid[x][y].GT.BottomLeft = (TileGrid[x][y].GT.BottomLeft * 10) + Current - 48;
        }
        else if (counter == 5) {
            TileGrid[x][y].GT.BottomRight = (TileGrid[x][y].GT.BottomRight * 10) + Current - 48;
        }

    }

    infile.close();
}

Visual Studio is giving me this error "Access Violation writing Location 0x00B0A654"

research online suggests that I'm reading data that doesn't exist but I'm unsure on how I can fix that.

Edit: forgot to mention that the error only occurs when writing the saving code.


Solution

  • Like other people already stated, a debugger is a great help in case of an error. Fortunately you have already found the error.

    Nevertheless, I think your code can be simplified. Overly complicated code is often a frustrating source of errors, and so it's always a major goal to keep the code as simple as possible. Your LoadFromFile() function is really complicated; I'm having a hard time to understand what's happening there. And you probably had too... like you said, the error was somewhere inside of your Current, x and so on declaration and if's.

    Here is a much simpler and much more understandable version of your LoadFromFile() / SaveToFile() functions.

    void LevelManager::SaveToFile( char * FileName ) {
        try {
            std::ofstream file( FileName );
            file.clear();
            for(unsigned y = 0; y < 300; y++) {
                for(unsigned x = 0; x < 300; x++) {
                    file << TileGrid[x][y].PhysicsNumber << "\n";
                    file << TileGrid[x][y].GT.TopLeft << "\n";
                    file << TileGrid[x][y].GT.TopRight << "\n";
                    file << TileGrid[x][y].GT.BottomLeft << "\n";
                    file << TileGrid[x][y].GT.BottomRight << "\n";
                }
            }
            file.close();
        } catch(...) {} //TODO: catch & evaluate file errors
    }
    
    void LevelManager::LoadFromFile( char * FileName ) {
        try {
            std::ifstream file( FileName );
            for(unsigned y = 0; y < 300; y++) {
                for(unsigned x = 0; x < 300; x++) {
                    file >> TileGrid[x][y].PhysicsNumber;
                    file >> TileGrid[x][y].GT.TopLeft;
                    file >> TileGrid[x][y].GT.TopRight;
                    file >> TileGrid[x][y].GT.BottomLeft;
                    file >> TileGrid[x][y].GT.BottomRight;
                }
            }
            file.close();
        } catch(...) {} //TODO: catch & evaluate file errors
    }
    

    This time, the LoadFromFile() is much easier to understand. And you could even simplify this more by writing an operator, which pushes/pops a complete TileGrid element to/from a stream.

    I have roughly tested this code in a test environment; please let me know if you need the whole file.