简体   繁体   中英

C++, Access violation

I have started to learn C++ some weeks ago and now I have a problem with my current project.

I wanted to write templates, that allow me to save objects into binary datas and load them again later. Here ist the code of these templates:

#ifndef TOOLS_H
#define TOOLS_H

#include <fstream>
#include <string>

namespace Tools
{
    template <class T>
    void writeBinaryFile(std::string filename, T object)
    {
        std::ofstream of(filename, std::ios::out | std::ios::binary);
        of.write((char*) &object, sizeof(T));
        of.close();
    }

    template <class P>
    P readBinaryFile(std::string filename)
    {
        P temp;
        std::ifstream ifs(filename, std::ios::in | std::ios::binary);
        ifs.read((char*) &temp, sizeof(P));
        ifs.close();
        return temp;
    }
}

#endif

I created a class called GameSettings. The header data is:

#ifndef GAMESETTINGS_H
#define GAMESETTINGS_H

#include <iostream>
#include <string>
#include "SFML\Graphics.hpp"

class GameSettings
{
public:
    GameSettings();
    GameSettings(std::string playerName, bool sound, int volume, int level);
    ~GameSettings();

    void setPlayerName(std::string playername){ playerName = playername; };
    void setSound(bool sound){ this->sound = sound; };
    void setVolume(int volume){ this->volume = volume; };
    void setLevel(int level){ this->level = level; };

    const std::string getPlayerName() { return playerName; }
    const bool getSound() { return sound; }
    const int getVolume() { return volume; }
    const int getLevel() { return level; }

private:
    std::string playerName;
    bool sound;
    int volume;
    int level;
};

#endif

With the cpp-data:

#include "GameSettings.h"

GameSettings::GameSettings(std::string playerName, bool sound, int volume, int level)
{
    this->playerName = playerName;
    this->sound = sound;
    this->volume = volume;
    this->level = level;
}

GameSettings::GameSettings():
playerName(""),
sound(true),
volume(0),
level(0)
{
}

GameSettings::~GameSettings()
{
}

When I start the main-function:

#include <iostream>
#include "GameSettings.h"
#include "Tools.h"

    int main()
    {
        GameSettings* gs = new GameSettings("Andrew", true, 100, 3);
        Tools::writeBinaryFile<GameSettings>("gamesettings.bin", *gs);

        gs->setPlayerName("TEST");

        *gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");

        std::cout << gs->getPlayerName();
        std::getchar();

        return 0;
    }

an error occurs:

Unhandled exception at 0x5a1cad54 (msvcp100d.dll) in Mohrhuhn.exe: 0xC0000005: Access violation writing location 0xfeeefeee.

Can somebody help me?

Sincerly, Andrew

I think the root of the trouble is

*gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");

You read raw bytes to a variable that contains std::string. It may ruin char pointer inside it. So, any call to playerName should fail or result in UB.

Only POD types can be read/write this way. A bit more I found on another web-page: http://www.cplusplus.com/forum/general/39764/

The template you implement to serialize the object will not work because casting the std::string to char* and saving sizeof(std::string) will not save the content of the string.

Check the saved file, but I guess you need to implement properly serialization and deserialization.

First of all writing down binary files by just dumping them from memory is a bad idea since you might incur in lots of additional problems (eg shallow copies, polimorphism, etc..)

    return temp;

You are returning a temporary object that is being destroyed after the function exits.

Change your code into

gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");

...

template <class P>
P* readBinaryFile(std::string filename)
{
    P* temp = new P();
    std::ifstream ifs(filename, std::ios::in | std::ios::binary);
    ifs.read((char*) temp, sizeof(P));
    ifs.close();
    return temp;
}

and everything will work out properly (psst. remember to free the memory!)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM