Save user defined data type to a file in C++
I have a class like this:
struct SomeClass{
SomeClass(){}
SomeClass(const SomeClass& rhs):
_m1(rhs._m1),
_m2(rhs._m2),
_m3(rhs._m3),
_m4(rhs._m4){}
SomeClass& operator=(const SomeClass& rhs){
// same as above
return *this;
}
int _m1;
std::vector<int> _m2;
std::vector<int> _m3;
int _m4;
};
At some point in my program, I want to save the data stored in a SomeClass
object for later use:
SomeClass someObj = arr->getBest(); // arr is a pointer to AnotherClass,
// in which different SomeClass
// objects are initialized and then
// involved in various
// computations in AnotherClass,
// finally the best one SomeClass
// object will be save here
fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
After the file being saved to saveFile
, I try to read it and get an error:
SomeClass readingSomeObj;
fread(&readingSomeObj, sizeof(SomeClass), 1, savedFile));
Compiler complaints "Access violation reading location 0x...". By watching the locals in VS, I see that the other two fields of readingSomeObj
, namely _m1
and _m4
have values in them but not _m2
and _m3
, in VS it says "unable to read memory".
It further relates the problem to the SomeClass
, specifically this line _m2(rhs._m2),
.
But when I was saving the someObj
in the line fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
I did see the two members _m2
and _m3
of someObj
have values (by hovering my mouse over &someObj
).
I can't figure out what was going wrong. My guess is problem with constructors of SomeClass
, but still as a newbie to C++, I don't know how to correct it. In other parts of my program, I used the empty constructor of SomeClass
to initialize a member of AnotherClass
. But everything runs fine except for this saving/reading part. I am looking for your generous help and thanks a million!
c++ fwrite fread
add a comment |
I have a class like this:
struct SomeClass{
SomeClass(){}
SomeClass(const SomeClass& rhs):
_m1(rhs._m1),
_m2(rhs._m2),
_m3(rhs._m3),
_m4(rhs._m4){}
SomeClass& operator=(const SomeClass& rhs){
// same as above
return *this;
}
int _m1;
std::vector<int> _m2;
std::vector<int> _m3;
int _m4;
};
At some point in my program, I want to save the data stored in a SomeClass
object for later use:
SomeClass someObj = arr->getBest(); // arr is a pointer to AnotherClass,
// in which different SomeClass
// objects are initialized and then
// involved in various
// computations in AnotherClass,
// finally the best one SomeClass
// object will be save here
fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
After the file being saved to saveFile
, I try to read it and get an error:
SomeClass readingSomeObj;
fread(&readingSomeObj, sizeof(SomeClass), 1, savedFile));
Compiler complaints "Access violation reading location 0x...". By watching the locals in VS, I see that the other two fields of readingSomeObj
, namely _m1
and _m4
have values in them but not _m2
and _m3
, in VS it says "unable to read memory".
It further relates the problem to the SomeClass
, specifically this line _m2(rhs._m2),
.
But when I was saving the someObj
in the line fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
I did see the two members _m2
and _m3
of someObj
have values (by hovering my mouse over &someObj
).
I can't figure out what was going wrong. My guess is problem with constructors of SomeClass
, but still as a newbie to C++, I don't know how to correct it. In other parts of my program, I used the empty constructor of SomeClass
to initialize a member of AnotherClass
. But everything runs fine except for this saving/reading part. I am looking for your generous help and thanks a million!
c++ fwrite fread
2
When you read and writeSomeClass
as you're doing, you're treating it as a raw (plain-old-data, or POD) structure of bytes. The bytes are no doubt correctly written out and read back in, but the contents of these bytes are no longer correct when you have pointers involved -- as is the case for the guts ofstd::vector
.
– Cameron
Nov 23 '18 at 17:48
@Cameron Answers in the answer section please and thank you
– Lightness Races in Orbit
Nov 23 '18 at 17:50
add a comment |
I have a class like this:
struct SomeClass{
SomeClass(){}
SomeClass(const SomeClass& rhs):
_m1(rhs._m1),
_m2(rhs._m2),
_m3(rhs._m3),
_m4(rhs._m4){}
SomeClass& operator=(const SomeClass& rhs){
// same as above
return *this;
}
int _m1;
std::vector<int> _m2;
std::vector<int> _m3;
int _m4;
};
At some point in my program, I want to save the data stored in a SomeClass
object for later use:
SomeClass someObj = arr->getBest(); // arr is a pointer to AnotherClass,
// in which different SomeClass
// objects are initialized and then
// involved in various
// computations in AnotherClass,
// finally the best one SomeClass
// object will be save here
fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
After the file being saved to saveFile
, I try to read it and get an error:
SomeClass readingSomeObj;
fread(&readingSomeObj, sizeof(SomeClass), 1, savedFile));
Compiler complaints "Access violation reading location 0x...". By watching the locals in VS, I see that the other two fields of readingSomeObj
, namely _m1
and _m4
have values in them but not _m2
and _m3
, in VS it says "unable to read memory".
It further relates the problem to the SomeClass
, specifically this line _m2(rhs._m2),
.
But when I was saving the someObj
in the line fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
I did see the two members _m2
and _m3
of someObj
have values (by hovering my mouse over &someObj
).
I can't figure out what was going wrong. My guess is problem with constructors of SomeClass
, but still as a newbie to C++, I don't know how to correct it. In other parts of my program, I used the empty constructor of SomeClass
to initialize a member of AnotherClass
. But everything runs fine except for this saving/reading part. I am looking for your generous help and thanks a million!
c++ fwrite fread
I have a class like this:
struct SomeClass{
SomeClass(){}
SomeClass(const SomeClass& rhs):
_m1(rhs._m1),
_m2(rhs._m2),
_m3(rhs._m3),
_m4(rhs._m4){}
SomeClass& operator=(const SomeClass& rhs){
// same as above
return *this;
}
int _m1;
std::vector<int> _m2;
std::vector<int> _m3;
int _m4;
};
At some point in my program, I want to save the data stored in a SomeClass
object for later use:
SomeClass someObj = arr->getBest(); // arr is a pointer to AnotherClass,
// in which different SomeClass
// objects are initialized and then
// involved in various
// computations in AnotherClass,
// finally the best one SomeClass
// object will be save here
fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
After the file being saved to saveFile
, I try to read it and get an error:
SomeClass readingSomeObj;
fread(&readingSomeObj, sizeof(SomeClass), 1, savedFile));
Compiler complaints "Access violation reading location 0x...". By watching the locals in VS, I see that the other two fields of readingSomeObj
, namely _m1
and _m4
have values in them but not _m2
and _m3
, in VS it says "unable to read memory".
It further relates the problem to the SomeClass
, specifically this line _m2(rhs._m2),
.
But when I was saving the someObj
in the line fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
I did see the two members _m2
and _m3
of someObj
have values (by hovering my mouse over &someObj
).
I can't figure out what was going wrong. My guess is problem with constructors of SomeClass
, but still as a newbie to C++, I don't know how to correct it. In other parts of my program, I used the empty constructor of SomeClass
to initialize a member of AnotherClass
. But everything runs fine except for this saving/reading part. I am looking for your generous help and thanks a million!
c++ fwrite fread
c++ fwrite fread
edited Nov 23 '18 at 17:45
SiggiSv
1,0931718
1,0931718
asked Nov 23 '18 at 17:42
tmshtmsh
176
176
2
When you read and writeSomeClass
as you're doing, you're treating it as a raw (plain-old-data, or POD) structure of bytes. The bytes are no doubt correctly written out and read back in, but the contents of these bytes are no longer correct when you have pointers involved -- as is the case for the guts ofstd::vector
.
– Cameron
Nov 23 '18 at 17:48
@Cameron Answers in the answer section please and thank you
– Lightness Races in Orbit
Nov 23 '18 at 17:50
add a comment |
2
When you read and writeSomeClass
as you're doing, you're treating it as a raw (plain-old-data, or POD) structure of bytes. The bytes are no doubt correctly written out and read back in, but the contents of these bytes are no longer correct when you have pointers involved -- as is the case for the guts ofstd::vector
.
– Cameron
Nov 23 '18 at 17:48
@Cameron Answers in the answer section please and thank you
– Lightness Races in Orbit
Nov 23 '18 at 17:50
2
2
When you read and write
SomeClass
as you're doing, you're treating it as a raw (plain-old-data, or POD) structure of bytes. The bytes are no doubt correctly written out and read back in, but the contents of these bytes are no longer correct when you have pointers involved -- as is the case for the guts of std::vector
.– Cameron
Nov 23 '18 at 17:48
When you read and write
SomeClass
as you're doing, you're treating it as a raw (plain-old-data, or POD) structure of bytes. The bytes are no doubt correctly written out and read back in, but the contents of these bytes are no longer correct when you have pointers involved -- as is the case for the guts of std::vector
.– Cameron
Nov 23 '18 at 17:48
@Cameron Answers in the answer section please and thank you
– Lightness Races in Orbit
Nov 23 '18 at 17:50
@Cameron Answers in the answer section please and thank you
– Lightness Races in Orbit
Nov 23 '18 at 17:50
add a comment |
2 Answers
2
active
oldest
votes
You can't serialize vectors like this. They have memory allocated, so do something like:
- Store your integers to the file
- Store the size of the first vector
- Store the content of your first vector
- Do the same for the second vector
Then when you read your file:
- Read your two integers
- Read your first vector size, allocate the vector
- Read the values for your first vector
- Do the same for the second vector.
You can also use a serialization library like Boost.Serialization that takes care of pieces of this in a more reliable way.
add a comment |
You've made a ton of assumptions about your data type that do not hold. The most egregious is that all its bytes are stored in a "row" in memory, all next to each other, which is the only way a block-wise copy-and-read could ever work.
This may hold for PODs (modulo alignment and endianness considerations) but it won't work for complex datatypes like vector
, that point to "real" data actually stored elsewhere (via dynamic allocation).
Your deserialised vectors consist pretty much solely of pointer values that are long-since invalid.
Your serialisation routine will have to be more intelligent than this. Ultimately there's no "one" way to do it. You can define your own format or you can use some off-the-shelf serialisation solution that already has a format that supports standard containers.
You could Google "C++ class serialisation" for some ideas.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451005%2fsave-user-defined-data-type-to-a-file-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can't serialize vectors like this. They have memory allocated, so do something like:
- Store your integers to the file
- Store the size of the first vector
- Store the content of your first vector
- Do the same for the second vector
Then when you read your file:
- Read your two integers
- Read your first vector size, allocate the vector
- Read the values for your first vector
- Do the same for the second vector.
You can also use a serialization library like Boost.Serialization that takes care of pieces of this in a more reliable way.
add a comment |
You can't serialize vectors like this. They have memory allocated, so do something like:
- Store your integers to the file
- Store the size of the first vector
- Store the content of your first vector
- Do the same for the second vector
Then when you read your file:
- Read your two integers
- Read your first vector size, allocate the vector
- Read the values for your first vector
- Do the same for the second vector.
You can also use a serialization library like Boost.Serialization that takes care of pieces of this in a more reliable way.
add a comment |
You can't serialize vectors like this. They have memory allocated, so do something like:
- Store your integers to the file
- Store the size of the first vector
- Store the content of your first vector
- Do the same for the second vector
Then when you read your file:
- Read your two integers
- Read your first vector size, allocate the vector
- Read the values for your first vector
- Do the same for the second vector.
You can also use a serialization library like Boost.Serialization that takes care of pieces of this in a more reliable way.
You can't serialize vectors like this. They have memory allocated, so do something like:
- Store your integers to the file
- Store the size of the first vector
- Store the content of your first vector
- Do the same for the second vector
Then when you read your file:
- Read your two integers
- Read your first vector size, allocate the vector
- Read the values for your first vector
- Do the same for the second vector.
You can also use a serialization library like Boost.Serialization that takes care of pieces of this in a more reliable way.
answered Nov 23 '18 at 17:48
Matthieu BrucherMatthieu Brucher
15.9k32141
15.9k32141
add a comment |
add a comment |
You've made a ton of assumptions about your data type that do not hold. The most egregious is that all its bytes are stored in a "row" in memory, all next to each other, which is the only way a block-wise copy-and-read could ever work.
This may hold for PODs (modulo alignment and endianness considerations) but it won't work for complex datatypes like vector
, that point to "real" data actually stored elsewhere (via dynamic allocation).
Your deserialised vectors consist pretty much solely of pointer values that are long-since invalid.
Your serialisation routine will have to be more intelligent than this. Ultimately there's no "one" way to do it. You can define your own format or you can use some off-the-shelf serialisation solution that already has a format that supports standard containers.
You could Google "C++ class serialisation" for some ideas.
add a comment |
You've made a ton of assumptions about your data type that do not hold. The most egregious is that all its bytes are stored in a "row" in memory, all next to each other, which is the only way a block-wise copy-and-read could ever work.
This may hold for PODs (modulo alignment and endianness considerations) but it won't work for complex datatypes like vector
, that point to "real" data actually stored elsewhere (via dynamic allocation).
Your deserialised vectors consist pretty much solely of pointer values that are long-since invalid.
Your serialisation routine will have to be more intelligent than this. Ultimately there's no "one" way to do it. You can define your own format or you can use some off-the-shelf serialisation solution that already has a format that supports standard containers.
You could Google "C++ class serialisation" for some ideas.
add a comment |
You've made a ton of assumptions about your data type that do not hold. The most egregious is that all its bytes are stored in a "row" in memory, all next to each other, which is the only way a block-wise copy-and-read could ever work.
This may hold for PODs (modulo alignment and endianness considerations) but it won't work for complex datatypes like vector
, that point to "real" data actually stored elsewhere (via dynamic allocation).
Your deserialised vectors consist pretty much solely of pointer values that are long-since invalid.
Your serialisation routine will have to be more intelligent than this. Ultimately there's no "one" way to do it. You can define your own format or you can use some off-the-shelf serialisation solution that already has a format that supports standard containers.
You could Google "C++ class serialisation" for some ideas.
You've made a ton of assumptions about your data type that do not hold. The most egregious is that all its bytes are stored in a "row" in memory, all next to each other, which is the only way a block-wise copy-and-read could ever work.
This may hold for PODs (modulo alignment and endianness considerations) but it won't work for complex datatypes like vector
, that point to "real" data actually stored elsewhere (via dynamic allocation).
Your deserialised vectors consist pretty much solely of pointer values that are long-since invalid.
Your serialisation routine will have to be more intelligent than this. Ultimately there's no "one" way to do it. You can define your own format or you can use some off-the-shelf serialisation solution that already has a format that supports standard containers.
You could Google "C++ class serialisation" for some ideas.
answered Nov 23 '18 at 17:48
Lightness Races in OrbitLightness Races in Orbit
290k51473803
290k51473803
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451005%2fsave-user-defined-data-type-to-a-file-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
When you read and write
SomeClass
as you're doing, you're treating it as a raw (plain-old-data, or POD) structure of bytes. The bytes are no doubt correctly written out and read back in, but the contents of these bytes are no longer correct when you have pointers involved -- as is the case for the guts ofstd::vector
.– Cameron
Nov 23 '18 at 17:48
@Cameron Answers in the answer section please and thank you
– Lightness Races in Orbit
Nov 23 '18 at 17:50