Witaj, więc mam trzy zajęcia i próbuję odesłać ich za pomocą zwiększenia

class WorldItem
{
private:
    friend class boost::serialization::access;
    template <class Archieve>
    void serialize(Archieve &ar, const unsigned int version)
    {
        ar &foreground;
        ar &background;
        ar &breakLevel;
        ar &breakTime;
        ar &water;
        ar &fire;
        ar &glue;
        ar &red;
        ar &green;
        ar &blue;
    }

public:
    int foreground = 0;
    int background = 0;
    int breakLevel = 0;
    long long int breakTime = 0;
    bool water = false;
    bool fire = false;
    bool glue = false;
    bool red = false;
    bool green = false;
    bool blue = false;
};

class Worlds
{
private:
    friend class boost::serialization::access;
    template <class Archieve>
    void serialize(Archieve &ar, const unsigned int version)
    {
        ar &width;
        ar &height;
        ar &name;
        for (int i = 0; i < 100 * 60; i++)
        {
            ar &items[i];
        }
        ar &owner;
        ar &weather;
        ar &isPublic;
        ar &isNuked;
    }

public:
    int width;
    int height;
    string name;
    WorldItem *items;
    string owner = "";
    int weather = 0;
    bool isPublic = false;
    bool isNuked = false;
};

Więc tutaj tworzę w ten sposób świat

Worlds generateWorld(string name, int width, int height)
{
    Worlds world;
    world.name = name;
    world.width = width;
    world.height = height;
    world.items = new WorldItem[100 * 60];
 }

I tutaj używam tej funkcji, aby serializować świat

std::stringstream serialize_world(Worlds world)
{
    std::stringstream str;
    {
        boost::archive::binary_oarchive oa(str);
        oa << world;
    }
    return str;
}

Dzięki temu funkcja Serializse_World działa bez problemów i wkładam wartość IT do MySQL LongBlob, ale teraz, gdy próbuję zdobyć BLOB z MySQL i Deserializacji go z powrotem za pomocą tej funkcji

Worlds deserialize(std::string world)
{

    Worlds wld;
    std::istream *blobdata = WORLD_DATA(world);
    {
    boost::archive::binary_iarchive ia(*blobdata);
    ia >> wld;
    }
    return wld;
}

Uzyskam błąd segmentacji (rdzeń porzucony) nie wiem, co się dzieje.

1
cmdocmd 13 marzec 2021, 21:02

1 odpowiedź

Najlepsza odpowiedź

Wygląda na to, że nigdy nie zwracasz wartości od generateWorld.

Mój kompilator ostrzega o tym. Spróbuj umożliwić diagnostykę kompilatora. Zwykle mam -Wall -Wextra -pedantic

Również w deserialize nigdy nie zainicjujesz items do niczego. To doprowadzi do UB.

To też można również zdiagnozować przez większość kompilatorów ({X0}} pomaga, choć sprawia, że kompilacja i wykonawcza wolno). Jest też narzędzia zewnętrzne, takie jak Valgrind, które to robią

Wreszcie nie mam pojęcia, co dzieje się z blobdata, więc ignoruję to, ale to też wygląda źle.

Nie używaj surowego nowego / usuwania

Zobacz także np. https://www.quora.com/why-are-The-%E2%80%98New%E2%80%99-In-% E2% 80% 98DELETE% E2% 80% 99-Uważany - Bad-in-Modern-C ++

Po prostu użyj std::array wtedy i bądź szczęśliwy:

Live on Coliru

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/array.hpp>
#include <array>
#include <iostream>
#include <sstream>

class WorldItem {
  private:
    friend class boost::serialization::access;
    template <class Ar> void serialize(Ar& ar, unsigned) {
        ar& foreground& background& breakLevel& breakTime& water& fire& glue&
            red& green& blue;
    }

  public:
    int foreground          = 0;
    int background          = 0;
    int breakLevel          = 0;
    long long int breakTime = 0;
    bool water              = false;
    bool fire               = false;
    bool glue               = false;
    bool red                = false;
    bool green              = false;
    bool blue               = false;

    auto operator<=>(WorldItem const&) const = default;
};

class Worlds
{
  private:
    friend class boost::serialization::access;
    template <class Ar> void serialize(Ar& ar, unsigned) {
        ar& width& height& name& items& owner& weather& isPublic& isNuked;
    }

  public:
    int width;
    int height;
    std::string name;

    std::array<WorldItem, 100 * 60> items;
    std::string owner = "";
    int weather       = 0;
    bool isPublic     = false;
    bool isNuked      = false;

    auto operator<=>(Worlds const&) const = default;
};
//So here im creating a world in this way

Worlds generateWorld(std::string name, int width, int height) {
    Worlds world;
    world.name   = name;
    world.width = width;
    world.height = height;
    return world;
}

std::string serialize_world(Worlds const& world) {
    std::stringstream str;
    {
        boost::archive::binary_oarchive oa(str);
        oa << world;
    }
    return str.str();
}

Worlds deserialize(std::string world) {
    Worlds wld;
    std::istringstream blobdata(world);
    {
        boost::archive::binary_iarchive ia(blobdata);
        ia >> wld;
    }
    return wld;
}

int main() {
    Worlds w = generateWorld("test", 6, 6);

    Worlds clone = deserialize(serialize_world(w));

    std::cout << "Worlds equal? " << std::boolalpha << (w == clone) << "\n";
}

Wydruki

Worlds equal? true
2
sehe 13 marzec 2021, 23:37