2014-11-20 20 views
0

У меня есть приложение, в котором мне нужны некоторые данные для сохранения, поэтому я подумал о сериализации объектов. Я нашел хороший пример here. После этого, это то, что я придумал:Невозможно сериализовать и десериализовать стек строк в Qt/C++

std::stack <std::string> cards; 
    cards.push("King of Hearts"); 
    std::ofstream ofs("<location>", std::ios::binary); 
    ofs.write((char *)&cards, sizeof(cards)); 
    ofs.close(); 

Тогда я пытаюсь прочитать данные:

std::stack<std::string> inp; 
    std::ifstream ifs("<same_location>", std::ios::binary); 
    ifs.read((char *)&inp, sizeof(inp)); 

Однако приложение сбой в последней строке (по какой-то причине, из-за мои настройки Qt, я не могу отлаживать в настоящее время). Какая может быть возможная ошибка, и как я могу это исправить?

+0

Вы не можете просто вывести произвольный класс в файл и прочитать его так и ожидать, что он будет работать. Самый безопасный способ - перебирать структуру данных и выводить один за другим. std :: stack не позволяет вам это делать, потому что это глупо. Вместо этого используйте std :: vector или std :: deque. –

ответ

0

Короткий ответ: вы не можете сериализовать стек так же, как описано в статье. Я бы сказал, что вы можете только сериализовать POD таким образом. Проблема в том, что данные, которые вы хотите записать, не сохраняются непрерывно в памяти, и с помощью ofs.write((char *)&cards, sizeof(cards)); вы не принимаете во внимание указатели на другие места в памяти.

Попробуйте этот эксперимент: как этот размер (карты) не изменяется, когда вы добавляете в него все больше и больше данных?

0
  1. Ваша проблема заключается в том, что вы предполагаете свойства стека, которые не соответствуют действительности. std :: stack по умолчанию использует deque в качестве базовой структуры, поэтому элементы не смежные в памяти.
  2. Вы никогда не должны предполагать, что структуры данных, которыми вы не являетесь, безопасны для произвольной сериализации. В C++ предпочтительной парадигмой является использование >> и < < операторов потока, поскольку преобразования могут иметь место.
  3. sizeof() получает только размер объекта в памяти, а не размер любого указателя данных. sizeof(), чтобы получить количество элементов в контейнере, приведет к бесполезным значениям.

Чтобы исправить эти проблемы, вы должны написать свои собственные операторы потока для сериализации в макете, который, как вы знаете, у вас есть.