簡體   English   中英

C ++,訪問沖突

[英]C++, Access violation

我幾周前開始學習C ++,現在我的當前項目出了問題。

我想編寫模板,允許我將對象保存到二進制數據中,然后再加載它們。 這是這些模板的代碼:

#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

我創建了一個名為GameSettings的類。 標題數據是:

#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

使用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()
{
}

當我啟動主函數時:

#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;
    }

發生錯誤:

Mohrhuhn.exe中0x5a1cad54(msvcp100d.dll)的未處理異常:0xC0000005:訪問沖突寫入位置0xfeeefeee。

有人能幫助我嗎?

真誠的,安德魯

我認為問題的根源在於

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

您將原始字節讀取到包含std :: string的變量。 它可能會破壞它內部的char指針。 因此,對playerName的任何調用都應該失敗或導致UB。

這種方式只能讀/寫POD類型。 我在另一個網頁上找到了更多: http//www.cplusplus.com/forum/general/39764/

您實現序列化對象的模板將無法工作,因為將std::stringchar*並保存sizeof(std::string)將不會保存字符串的內容。

檢查保存的文件,但我想你需要實現正確的序列化和反序列化。

首先通過從內存中轉儲二進制文件來寫下二進制文件是一個壞主意,因為你可能會遇到許多其他問題(例如淺拷貝,polimorphism等等)。

    return temp;

您將返回一個臨時對象,該對象在函數退出后被銷毀。

將您的代碼更改為

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

一切都會正常運作(psst。記得釋放記憶!)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM