I'm having some problems when learning how to use protobuf data format with C++.
And this is what i did.
syntax = "proto2";
package test;
message studentInfo {
optional string id = 1;
optional string name = 2;
optional item3 favority = 3;
optional int32 age = 4;
optional item6 skills = 6;
}
message item3 {
optional string name = 1;
}
message item6 {
optional skillName skills = 4;
optional skillslot size = 5;
}
message skillName {
optional string skill1 = 1;
optional string skill2 = 2;
}
message skillslot {
optional int32 size = 1;
}
2.And then this is the code i wrote.
#include "test.pb.h"
#include <fstream>
#pragma comment(lib,"libprotoc.lib")
#pragma comment(lib,"libprotobuf.lib")
const std::string c_strID = "555222333";
const std::string c_strName = "cat";
const std::string c_strFav = "Apple";
const std::string c_strSkill = "Sleep";
const std::string c_strSkill2 = "Eat";
constexpr int c_iAge = 21;
constexpr int c_iSkillCount = 2;
const std::string c_strPath = "D:\\test.txt";
void RunPBTest()
{
GOOGLE_PROTOBUF_VERSION;
{
test::studentInfo stu;
//id
stu.set_id(c_strID.c_str());
//name
stu.set_name(c_strName.c_str());
//favority
test::item3 itemFav;
itemFav.set_name(c_strFav.c_str());
stu.set_allocated_favority(&itemFav);
//age
stu.set_age(c_iAge);
//skills
test::skillName itemSkillList;
itemSkillList.set_skill1(c_strSkill);
itemSkillList.set_skill2(c_strSkill2);
test::skillslot itemSlot;
itemSlot.set_size(c_iSkillCount);
test::item6 itemSkills;
itemSkills.set_allocated_skills(&itemSkillList);
itemSkills.set_allocated_size(&itemSlot);
stu.set_allocated_skills(&itemSkills);
//output
{
std::fstream output(c_strPath, std::ios::out | std::ios::trunc | std::ios::binary);
if (output.is_open())
{
stu.SerializePartialToOstream(&output);
output.close();
}
}
google::protobuf::ShutdownProtobufLibrary();
}
}
int main()
{
RunPBTest();
return 0;
}
3.Finally,it throws an exception when executing "delete skills_".
I guess because that variable is freed twice.So for try to solve this problem i wrote the following code.
#include "test.pb.h"
#include <memory>
#include <fstream>
#pragma comment(lib,"libprotoc.lib")
#pragma comment(lib,"libprotobuf.lib")
const std::string c_strID = "555222333";
const std::string c_strName = "cat";
const std::string c_strFav = "Apple";
const std::string c_strSkill = "Sleep";
const std::string c_strSkill2 = "Eat";
constexpr int c_iAge = 21;
constexpr int c_iSkillCount = 2;
const std::string c_strPath = "D:\\test.txt";
void RunPBTest()
{
GOOGLE_PROTOBUF_VERSION;
{
std::shared_ptr<test::studentInfo> spStu(new test::studentInfo);
//id
spStu->set_id(c_strID.c_str());
//name
spStu->set_name(c_strName.c_str());
//favority
std::shared_ptr<test::item3> spFav(new test::item3);
spFav->set_name(c_strFav.c_str());
std::weak_ptr<test::item3> wpFav = spFav;
spStu->set_allocated_favority(&*wpFav.lock());
//age
spStu->set_age(c_iAge);
//skills
std::shared_ptr<test::skillName> spSkillList(new test::skillName);
spSkillList->set_skill1(c_strSkill);
spSkillList->set_skill2(c_strSkill2);
std::shared_ptr<test::skillslot> spSlot(new test::skillslot);
spSlot->set_size(c_iSkillCount);
std::shared_ptr<test::item6> spSkills(new test::item6);
std::weak_ptr<test::skillName> wpSkillList = spSkillList;
std::weak_ptr<test::skillslot> wpspSlot = spSlot;
spSkills->set_allocated_skills(&*wpSkillList.lock());
spSkills->set_allocated_size(&*wpspSlot.lock());
std::weak_ptr<test::item6> wpSkills = spSkills;
spStu->set_allocated_skills(&*wpSkills.lock());
//output
{
std::fstream output(c_strPath, std::ios::out | std::ios::trunc | std::ios::binary);
if (output.is_open())
{
spStu->SerializePartialToOstream(&output);
output.close();
}
}
google::protobuf::ShutdownProtobufLibrary();
}
}
int main()
{
RunPBTest();
return 0;
}
As the title says,It still crashes.
I am not sure what the problem is and what should I do to solve this prolem, hope someone can tell me...T^T
Thanks@ molbdnilo
Now I can write code that doesn't throw exceptions.
void RunPBTest()
{
GOOGLE_PROTOBUF_VERSION;
{
test::studentInfo pStu;
test::item3* pFav = pStu.mutable_favority();
test::item6* pSkills = pStu.mutable_skills();
test::skillName* pSkillList = pSkills->mutable_skills();
test::skillslot* pSkillSlot = pSkills->mutable_size();
pStu.set_id(c_strID.c_str());
pStu.set_name(c_strName.c_str());
pFav->set_name(c_strFav.c_str());
pStu.set_age(c_iAge);
pSkillList->set_skill1(c_strSkill);
pSkillList->set_skill2(c_strSkill2);
pSkillSlot->set_size(c_iSkillCount);
//output
{
std::fstream output(c_strPath, std::ios::out | std::ios::trunc | std::ios::binary);
if (output.is_open())
{
pStu.SerializePartialToOstream(&output);
output.close();
}
}
google::protobuf::ShutdownProtobufLibrary();
}
}