File I/O Binary Dynamic Array Crashed











up vote
1
down vote

favorite












#include iostream
#include cmath
#include fstream
#include cstdlib
#include string
using namespace std;
class Device {//Input and store Device Description and Serial Numbers
protected:
string serial_number;
string device_description;
public:
Device() {
serial_number = ("6DCMQ32");
device_description = ("TheDell");
}
};
class Test {//Input and store Test Description, recent day, and month;
Calculate the next day
protected:
string Test_Description;
static int recent_month, recent_day, recent_year, new_month;
static int nmonth, next_month, next_day, next_year, max_day;
public:
Test() {
Test_Description = ("Virtual");
}
static void getMonth(ostream & out) {//Calculates the next/new month
next_month = recent_month + nmonth;
new_month = next_month % 12;
if (next_month >= 12) {
cout << "The next Date: " << new_month << " / ";
}
else {
out << "The next Date: " << next_month << " / ";
}
}
static void getDay(ostream & out) { //Calculates day of next month
if (new_month == 4 || new_month == 6 || new_month == 9 || new_month == 11) {
max_day = 30;
}
else if (new_month == 2) {
max_day = 29;
}
else {
max_day = 31;
}
if (recent_day > max_day) {
out << max_day << " / ";
}
else {
out << recent_day << " / ";
}
}
static void getYear(ostream & out) {// Calculate the year of next month
next_year = recent_year + next_month;
if (next_year >= 12) {
out << recent_year + (next_month / 12) << endl;
}
else {
out << next_year << endl;
}
}
static void getDate(ostream & out) {// Collects the output of each element of next date
getMonth(out), getDay(out), getYear(out);
}
};
int Test::recent_month;
int Test::recent_day;
int Test::recent_year;
int Test::new_month;
int Test::nmonth;
int Test::next_month;
int Test::next_day;
int Test::next_year;
int Test::max_day;
class Lab : public Device, public Test {
protected:
static int n;
public:
friend istream & operator>>(istream & in, Lab & lab) {// Inputs
cout << "Enter Device Desciption and Serial Number: ";
getline(cin, lab.device_description);
getline(cin, lab.serial_number);
cout << "Enter Test Desciption: ";
getline(cin, lab.Test_Description);
cout << "Enter the Number of months: ";
in >> nmonth;
cout << "Enter the Most Recent Date(mm/dd/yyyy): ";
in >> recent_month >> recent_day >> recent_year;
return in;
}
friend ostream & operator<<(ostream & out, Lab & lab) {//Outputs everything in Device Class
out << lab.device_description << endl;
out << lab.serial_number << endl;
out << lab.Test_Description << endl;
getDate(out);
return out;
}
static void getN() {
cout << "Enter the number of devices: ";
cin >> n;
}
static void getWrite() {
Lab *obj = new Lab[n];
if (obj == 0) {
cout << "Memory Error";
exit(1);
}
for (int i = 0; i<n; i++) {
cin >> obj[i];
cout << endl;
}
ofstream myfile("Device.dat", ios::binary);
myfile.write((char*) obj, n * sizeof(Lab));
delete obj;
}
static void getRead() {
ifstream file2("Device.dat", ios::binary);
Lab *obj2 = new Lab[n];
if (obj2 == 0) {
cout << "Memory Error";
exit(1);
}
file2.read((char*) obj2, n * sizeof(Lab));
for (int i = 0; i < n; i++) {
cout << obj2[i];
cout << endl;
}
delete obj2;
}
};
int Lab::n;
void main() {
Lab L;
L.getN();
L.getWrite();
L.getRead();
getchar();
getchar();
system("pause");
}


The program keeps on crashing after outputting the values



Purpose: is to enter the number of months for the next test date of device with input of serial number,
Device Description, Test Description, recent date, and the number of months of two tests. At the end the
program must be searched by having the user to input the serial number and the next date, if these two are
valid everything in the device is listed out.



I am using Microsoft Visual Studios 2017










share|improve this question


















  • 1




    std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness.
    – user4581301
    Nov 20 at 1:11










  • Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code.
    – user4581301
    Nov 20 at 1:12






  • 1




    Use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.
    – user4581301
    Nov 20 at 1:15










  • I don't know what to do. Can you please help me?
    – Goodzone Lo
    Nov 20 at 1:15






  • 1




    @GoodzoneLo myfile.write((char*) obj, n * sizeof(Lab)) -- This would never work. The sizeof(Lab) remains the same value, regardless of how many characters the std::string members had in them. That alone makes this attempt futile. You're supposed to write the data that the object represents to a file so that when reading the data, you recreate the object. So you have to take that object, see what the pieces of data that makes up the object represents, and write that to a file (i.e. the characters in the strings, not the std::string itself).
    – PaulMcKenzie
    Nov 20 at 1:54

















up vote
1
down vote

favorite












#include iostream
#include cmath
#include fstream
#include cstdlib
#include string
using namespace std;
class Device {//Input and store Device Description and Serial Numbers
protected:
string serial_number;
string device_description;
public:
Device() {
serial_number = ("6DCMQ32");
device_description = ("TheDell");
}
};
class Test {//Input and store Test Description, recent day, and month;
Calculate the next day
protected:
string Test_Description;
static int recent_month, recent_day, recent_year, new_month;
static int nmonth, next_month, next_day, next_year, max_day;
public:
Test() {
Test_Description = ("Virtual");
}
static void getMonth(ostream & out) {//Calculates the next/new month
next_month = recent_month + nmonth;
new_month = next_month % 12;
if (next_month >= 12) {
cout << "The next Date: " << new_month << " / ";
}
else {
out << "The next Date: " << next_month << " / ";
}
}
static void getDay(ostream & out) { //Calculates day of next month
if (new_month == 4 || new_month == 6 || new_month == 9 || new_month == 11) {
max_day = 30;
}
else if (new_month == 2) {
max_day = 29;
}
else {
max_day = 31;
}
if (recent_day > max_day) {
out << max_day << " / ";
}
else {
out << recent_day << " / ";
}
}
static void getYear(ostream & out) {// Calculate the year of next month
next_year = recent_year + next_month;
if (next_year >= 12) {
out << recent_year + (next_month / 12) << endl;
}
else {
out << next_year << endl;
}
}
static void getDate(ostream & out) {// Collects the output of each element of next date
getMonth(out), getDay(out), getYear(out);
}
};
int Test::recent_month;
int Test::recent_day;
int Test::recent_year;
int Test::new_month;
int Test::nmonth;
int Test::next_month;
int Test::next_day;
int Test::next_year;
int Test::max_day;
class Lab : public Device, public Test {
protected:
static int n;
public:
friend istream & operator>>(istream & in, Lab & lab) {// Inputs
cout << "Enter Device Desciption and Serial Number: ";
getline(cin, lab.device_description);
getline(cin, lab.serial_number);
cout << "Enter Test Desciption: ";
getline(cin, lab.Test_Description);
cout << "Enter the Number of months: ";
in >> nmonth;
cout << "Enter the Most Recent Date(mm/dd/yyyy): ";
in >> recent_month >> recent_day >> recent_year;
return in;
}
friend ostream & operator<<(ostream & out, Lab & lab) {//Outputs everything in Device Class
out << lab.device_description << endl;
out << lab.serial_number << endl;
out << lab.Test_Description << endl;
getDate(out);
return out;
}
static void getN() {
cout << "Enter the number of devices: ";
cin >> n;
}
static void getWrite() {
Lab *obj = new Lab[n];
if (obj == 0) {
cout << "Memory Error";
exit(1);
}
for (int i = 0; i<n; i++) {
cin >> obj[i];
cout << endl;
}
ofstream myfile("Device.dat", ios::binary);
myfile.write((char*) obj, n * sizeof(Lab));
delete obj;
}
static void getRead() {
ifstream file2("Device.dat", ios::binary);
Lab *obj2 = new Lab[n];
if (obj2 == 0) {
cout << "Memory Error";
exit(1);
}
file2.read((char*) obj2, n * sizeof(Lab));
for (int i = 0; i < n; i++) {
cout << obj2[i];
cout << endl;
}
delete obj2;
}
};
int Lab::n;
void main() {
Lab L;
L.getN();
L.getWrite();
L.getRead();
getchar();
getchar();
system("pause");
}


The program keeps on crashing after outputting the values



Purpose: is to enter the number of months for the next test date of device with input of serial number,
Device Description, Test Description, recent date, and the number of months of two tests. At the end the
program must be searched by having the user to input the serial number and the next date, if these two are
valid everything in the device is listed out.



I am using Microsoft Visual Studios 2017










share|improve this question


















  • 1




    std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness.
    – user4581301
    Nov 20 at 1:11










  • Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code.
    – user4581301
    Nov 20 at 1:12






  • 1




    Use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.
    – user4581301
    Nov 20 at 1:15










  • I don't know what to do. Can you please help me?
    – Goodzone Lo
    Nov 20 at 1:15






  • 1




    @GoodzoneLo myfile.write((char*) obj, n * sizeof(Lab)) -- This would never work. The sizeof(Lab) remains the same value, regardless of how many characters the std::string members had in them. That alone makes this attempt futile. You're supposed to write the data that the object represents to a file so that when reading the data, you recreate the object. So you have to take that object, see what the pieces of data that makes up the object represents, and write that to a file (i.e. the characters in the strings, not the std::string itself).
    – PaulMcKenzie
    Nov 20 at 1:54















up vote
1
down vote

favorite









up vote
1
down vote

favorite











#include iostream
#include cmath
#include fstream
#include cstdlib
#include string
using namespace std;
class Device {//Input and store Device Description and Serial Numbers
protected:
string serial_number;
string device_description;
public:
Device() {
serial_number = ("6DCMQ32");
device_description = ("TheDell");
}
};
class Test {//Input and store Test Description, recent day, and month;
Calculate the next day
protected:
string Test_Description;
static int recent_month, recent_day, recent_year, new_month;
static int nmonth, next_month, next_day, next_year, max_day;
public:
Test() {
Test_Description = ("Virtual");
}
static void getMonth(ostream & out) {//Calculates the next/new month
next_month = recent_month + nmonth;
new_month = next_month % 12;
if (next_month >= 12) {
cout << "The next Date: " << new_month << " / ";
}
else {
out << "The next Date: " << next_month << " / ";
}
}
static void getDay(ostream & out) { //Calculates day of next month
if (new_month == 4 || new_month == 6 || new_month == 9 || new_month == 11) {
max_day = 30;
}
else if (new_month == 2) {
max_day = 29;
}
else {
max_day = 31;
}
if (recent_day > max_day) {
out << max_day << " / ";
}
else {
out << recent_day << " / ";
}
}
static void getYear(ostream & out) {// Calculate the year of next month
next_year = recent_year + next_month;
if (next_year >= 12) {
out << recent_year + (next_month / 12) << endl;
}
else {
out << next_year << endl;
}
}
static void getDate(ostream & out) {// Collects the output of each element of next date
getMonth(out), getDay(out), getYear(out);
}
};
int Test::recent_month;
int Test::recent_day;
int Test::recent_year;
int Test::new_month;
int Test::nmonth;
int Test::next_month;
int Test::next_day;
int Test::next_year;
int Test::max_day;
class Lab : public Device, public Test {
protected:
static int n;
public:
friend istream & operator>>(istream & in, Lab & lab) {// Inputs
cout << "Enter Device Desciption and Serial Number: ";
getline(cin, lab.device_description);
getline(cin, lab.serial_number);
cout << "Enter Test Desciption: ";
getline(cin, lab.Test_Description);
cout << "Enter the Number of months: ";
in >> nmonth;
cout << "Enter the Most Recent Date(mm/dd/yyyy): ";
in >> recent_month >> recent_day >> recent_year;
return in;
}
friend ostream & operator<<(ostream & out, Lab & lab) {//Outputs everything in Device Class
out << lab.device_description << endl;
out << lab.serial_number << endl;
out << lab.Test_Description << endl;
getDate(out);
return out;
}
static void getN() {
cout << "Enter the number of devices: ";
cin >> n;
}
static void getWrite() {
Lab *obj = new Lab[n];
if (obj == 0) {
cout << "Memory Error";
exit(1);
}
for (int i = 0; i<n; i++) {
cin >> obj[i];
cout << endl;
}
ofstream myfile("Device.dat", ios::binary);
myfile.write((char*) obj, n * sizeof(Lab));
delete obj;
}
static void getRead() {
ifstream file2("Device.dat", ios::binary);
Lab *obj2 = new Lab[n];
if (obj2 == 0) {
cout << "Memory Error";
exit(1);
}
file2.read((char*) obj2, n * sizeof(Lab));
for (int i = 0; i < n; i++) {
cout << obj2[i];
cout << endl;
}
delete obj2;
}
};
int Lab::n;
void main() {
Lab L;
L.getN();
L.getWrite();
L.getRead();
getchar();
getchar();
system("pause");
}


The program keeps on crashing after outputting the values



Purpose: is to enter the number of months for the next test date of device with input of serial number,
Device Description, Test Description, recent date, and the number of months of two tests. At the end the
program must be searched by having the user to input the serial number and the next date, if these two are
valid everything in the device is listed out.



I am using Microsoft Visual Studios 2017










share|improve this question













#include iostream
#include cmath
#include fstream
#include cstdlib
#include string
using namespace std;
class Device {//Input and store Device Description and Serial Numbers
protected:
string serial_number;
string device_description;
public:
Device() {
serial_number = ("6DCMQ32");
device_description = ("TheDell");
}
};
class Test {//Input and store Test Description, recent day, and month;
Calculate the next day
protected:
string Test_Description;
static int recent_month, recent_day, recent_year, new_month;
static int nmonth, next_month, next_day, next_year, max_day;
public:
Test() {
Test_Description = ("Virtual");
}
static void getMonth(ostream & out) {//Calculates the next/new month
next_month = recent_month + nmonth;
new_month = next_month % 12;
if (next_month >= 12) {
cout << "The next Date: " << new_month << " / ";
}
else {
out << "The next Date: " << next_month << " / ";
}
}
static void getDay(ostream & out) { //Calculates day of next month
if (new_month == 4 || new_month == 6 || new_month == 9 || new_month == 11) {
max_day = 30;
}
else if (new_month == 2) {
max_day = 29;
}
else {
max_day = 31;
}
if (recent_day > max_day) {
out << max_day << " / ";
}
else {
out << recent_day << " / ";
}
}
static void getYear(ostream & out) {// Calculate the year of next month
next_year = recent_year + next_month;
if (next_year >= 12) {
out << recent_year + (next_month / 12) << endl;
}
else {
out << next_year << endl;
}
}
static void getDate(ostream & out) {// Collects the output of each element of next date
getMonth(out), getDay(out), getYear(out);
}
};
int Test::recent_month;
int Test::recent_day;
int Test::recent_year;
int Test::new_month;
int Test::nmonth;
int Test::next_month;
int Test::next_day;
int Test::next_year;
int Test::max_day;
class Lab : public Device, public Test {
protected:
static int n;
public:
friend istream & operator>>(istream & in, Lab & lab) {// Inputs
cout << "Enter Device Desciption and Serial Number: ";
getline(cin, lab.device_description);
getline(cin, lab.serial_number);
cout << "Enter Test Desciption: ";
getline(cin, lab.Test_Description);
cout << "Enter the Number of months: ";
in >> nmonth;
cout << "Enter the Most Recent Date(mm/dd/yyyy): ";
in >> recent_month >> recent_day >> recent_year;
return in;
}
friend ostream & operator<<(ostream & out, Lab & lab) {//Outputs everything in Device Class
out << lab.device_description << endl;
out << lab.serial_number << endl;
out << lab.Test_Description << endl;
getDate(out);
return out;
}
static void getN() {
cout << "Enter the number of devices: ";
cin >> n;
}
static void getWrite() {
Lab *obj = new Lab[n];
if (obj == 0) {
cout << "Memory Error";
exit(1);
}
for (int i = 0; i<n; i++) {
cin >> obj[i];
cout << endl;
}
ofstream myfile("Device.dat", ios::binary);
myfile.write((char*) obj, n * sizeof(Lab));
delete obj;
}
static void getRead() {
ifstream file2("Device.dat", ios::binary);
Lab *obj2 = new Lab[n];
if (obj2 == 0) {
cout << "Memory Error";
exit(1);
}
file2.read((char*) obj2, n * sizeof(Lab));
for (int i = 0; i < n; i++) {
cout << obj2[i];
cout << endl;
}
delete obj2;
}
};
int Lab::n;
void main() {
Lab L;
L.getN();
L.getWrite();
L.getRead();
getchar();
getchar();
system("pause");
}


The program keeps on crashing after outputting the values



Purpose: is to enter the number of months for the next test date of device with input of serial number,
Device Description, Test Description, recent date, and the number of months of two tests. At the end the
program must be searched by having the user to input the serial number and the next date, if these two are
valid everything in the device is listed out.



I am using Microsoft Visual Studios 2017







c++ file oop file-writing file-read






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 at 1:03









Goodzone Lo

103




103








  • 1




    std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness.
    – user4581301
    Nov 20 at 1:11










  • Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code.
    – user4581301
    Nov 20 at 1:12






  • 1




    Use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.
    – user4581301
    Nov 20 at 1:15










  • I don't know what to do. Can you please help me?
    – Goodzone Lo
    Nov 20 at 1:15






  • 1




    @GoodzoneLo myfile.write((char*) obj, n * sizeof(Lab)) -- This would never work. The sizeof(Lab) remains the same value, regardless of how many characters the std::string members had in them. That alone makes this attempt futile. You're supposed to write the data that the object represents to a file so that when reading the data, you recreate the object. So you have to take that object, see what the pieces of data that makes up the object represents, and write that to a file (i.e. the characters in the strings, not the std::string itself).
    – PaulMcKenzie
    Nov 20 at 1:54
















  • 1




    std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness.
    – user4581301
    Nov 20 at 1:11










  • Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code.
    – user4581301
    Nov 20 at 1:12






  • 1




    Use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.
    – user4581301
    Nov 20 at 1:15










  • I don't know what to do. Can you please help me?
    – Goodzone Lo
    Nov 20 at 1:15






  • 1




    @GoodzoneLo myfile.write((char*) obj, n * sizeof(Lab)) -- This would never work. The sizeof(Lab) remains the same value, regardless of how many characters the std::string members had in them. That alone makes this attempt futile. You're supposed to write the data that the object represents to a file so that when reading the data, you recreate the object. So you have to take that object, see what the pieces of data that makes up the object represents, and write that to a file (i.e. the characters in the strings, not the std::string itself).
    – PaulMcKenzie
    Nov 20 at 1:54










1




1




std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness.
– user4581301
Nov 20 at 1:11




std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness.
– user4581301
Nov 20 at 1:11












Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code.
– user4581301
Nov 20 at 1:12




Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code.
– user4581301
Nov 20 at 1:12




1




1




Use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.
– user4581301
Nov 20 at 1:15




Use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.
– user4581301
Nov 20 at 1:15












I don't know what to do. Can you please help me?
– Goodzone Lo
Nov 20 at 1:15




I don't know what to do. Can you please help me?
– Goodzone Lo
Nov 20 at 1:15




1




1




@GoodzoneLo myfile.write((char*) obj, n * sizeof(Lab)) -- This would never work. The sizeof(Lab) remains the same value, regardless of how many characters the std::string members had in them. That alone makes this attempt futile. You're supposed to write the data that the object represents to a file so that when reading the data, you recreate the object. So you have to take that object, see what the pieces of data that makes up the object represents, and write that to a file (i.e. the characters in the strings, not the std::string itself).
– PaulMcKenzie
Nov 20 at 1:54






@GoodzoneLo myfile.write((char*) obj, n * sizeof(Lab)) -- This would never work. The sizeof(Lab) remains the same value, regardless of how many characters the std::string members had in them. That alone makes this attempt futile. You're supposed to write the data that the object represents to a file so that when reading the data, you recreate the object. So you have to take that object, see what the pieces of data that makes up the object represents, and write that to a file (i.e. the characters in the strings, not the std::string itself).
– PaulMcKenzie
Nov 20 at 1:54














1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness. Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code. Either way accessing memory that has not been assigned to the pointer invokes Undefined Behaviour, and with UB anything can happen. Don't count on crashes or consistency.



Generally you would use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.



The protocol is going to be a set of functions that convert simpler data types to and from their file equivalents.



A typical method for writing a string is to first write the length of the string and then write the contents of the string. Something like



uint32 len = str.length(); //fixed width length
len = htonl(len); // fixed endian
myfile.write((char*) &len, sizeof(len)); //write length
myfile.write(str.data(), str.length()); //write string


And reading



uint32 len; //fixed width length
myfile.read((char*) &len, sizeof(len)); //read length
len = ntohl(len); // unfix endian
std::string str(len, ' '); //string and allocate size
myfile.write(str.data(), len); //read string C++17 or
//myfile.write(&str[0], len); //read string before C++17


bundle these up inside functions and you've started on your protocol. Add to them functions for other data types you need to store.



These functions are then called by functions that convert larger datatypes and on up until you reach the most complex of the structures you need to write. For an array, use a loop. If you have a length of variable size, prefix the length just like with a string.



Side note: When reading or writing numbers care must be taken to ensure the number is a known, fixed size. int, for example, can be any size 16 bits or greater so long at it's not larger thanlong. You don't necessarily know that the file reader will be using the same sizedint`, so you should prefer a Fixed Width Integer large enough to store the values required. Different computers also may store their binary information in different orders. This is called Byte Order or Endian. Make sure everyone is using the same endian.






share|improve this answer





















    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',
    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
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384784%2ffile-i-o-binary-dynamic-array-crashed%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness. Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code. Either way accessing memory that has not been assigned to the pointer invokes Undefined Behaviour, and with UB anything can happen. Don't count on crashes or consistency.



    Generally you would use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.



    The protocol is going to be a set of functions that convert simpler data types to and from their file equivalents.



    A typical method for writing a string is to first write the length of the string and then write the contents of the string. Something like



    uint32 len = str.length(); //fixed width length
    len = htonl(len); // fixed endian
    myfile.write((char*) &len, sizeof(len)); //write length
    myfile.write(str.data(), str.length()); //write string


    And reading



    uint32 len; //fixed width length
    myfile.read((char*) &len, sizeof(len)); //read length
    len = ntohl(len); // unfix endian
    std::string str(len, ' '); //string and allocate size
    myfile.write(str.data(), len); //read string C++17 or
    //myfile.write(&str[0], len); //read string before C++17


    bundle these up inside functions and you've started on your protocol. Add to them functions for other data types you need to store.



    These functions are then called by functions that convert larger datatypes and on up until you reach the most complex of the structures you need to write. For an array, use a loop. If you have a length of variable size, prefix the length just like with a string.



    Side note: When reading or writing numbers care must be taken to ensure the number is a known, fixed size. int, for example, can be any size 16 bits or greater so long at it's not larger thanlong. You don't necessarily know that the file reader will be using the same sizedint`, so you should prefer a Fixed Width Integer large enough to store the values required. Different computers also may store their binary information in different orders. This is called Byte Order or Endian. Make sure everyone is using the same endian.






    share|improve this answer

























      up vote
      1
      down vote



      accepted










      std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness. Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code. Either way accessing memory that has not been assigned to the pointer invokes Undefined Behaviour, and with UB anything can happen. Don't count on crashes or consistency.



      Generally you would use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.



      The protocol is going to be a set of functions that convert simpler data types to and from their file equivalents.



      A typical method for writing a string is to first write the length of the string and then write the contents of the string. Something like



      uint32 len = str.length(); //fixed width length
      len = htonl(len); // fixed endian
      myfile.write((char*) &len, sizeof(len)); //write length
      myfile.write(str.data(), str.length()); //write string


      And reading



      uint32 len; //fixed width length
      myfile.read((char*) &len, sizeof(len)); //read length
      len = ntohl(len); // unfix endian
      std::string str(len, ' '); //string and allocate size
      myfile.write(str.data(), len); //read string C++17 or
      //myfile.write(&str[0], len); //read string before C++17


      bundle these up inside functions and you've started on your protocol. Add to them functions for other data types you need to store.



      These functions are then called by functions that convert larger datatypes and on up until you reach the most complex of the structures you need to write. For an array, use a loop. If you have a length of variable size, prefix the length just like with a string.



      Side note: When reading or writing numbers care must be taken to ensure the number is a known, fixed size. int, for example, can be any size 16 bits or greater so long at it's not larger thanlong. You don't necessarily know that the file reader will be using the same sizedint`, so you should prefer a Fixed Width Integer large enough to store the values required. Different computers also may store their binary information in different orders. This is called Byte Order or Endian. Make sure everyone is using the same endian.






      share|improve this answer























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness. Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code. Either way accessing memory that has not been assigned to the pointer invokes Undefined Behaviour, and with UB anything can happen. Don't count on crashes or consistency.



        Generally you would use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.



        The protocol is going to be a set of functions that convert simpler data types to and from their file equivalents.



        A typical method for writing a string is to first write the length of the string and then write the contents of the string. Something like



        uint32 len = str.length(); //fixed width length
        len = htonl(len); // fixed endian
        myfile.write((char*) &len, sizeof(len)); //write length
        myfile.write(str.data(), str.length()); //write string


        And reading



        uint32 len; //fixed width length
        myfile.read((char*) &len, sizeof(len)); //read length
        len = ntohl(len); // unfix endian
        std::string str(len, ' '); //string and allocate size
        myfile.write(str.data(), len); //read string C++17 or
        //myfile.write(&str[0], len); //read string before C++17


        bundle these up inside functions and you've started on your protocol. Add to them functions for other data types you need to store.



        These functions are then called by functions that convert larger datatypes and on up until you reach the most complex of the structures you need to write. For an array, use a loop. If you have a length of variable size, prefix the length just like with a string.



        Side note: When reading or writing numbers care must be taken to ensure the number is a known, fixed size. int, for example, can be any size 16 bits or greater so long at it's not larger thanlong. You don't necessarily know that the file reader will be using the same sizedint`, so you should prefer a Fixed Width Integer large enough to store the values required. Different computers also may store their binary information in different orders. This is called Byte Order or Endian. Make sure everyone is using the same endian.






        share|improve this answer












        std::string is far too complicated a data structure to simply write to a file unfortunately. At it's simplest, a string is a pointer to a character array and an integer storing the length of the array. When you write a pointer to a file, you write the address, not the data at the address. When you read the string back latter, odds are very good you wind up with a stale address pointing to memory that the program does not own and much crashing badness. Worse is if the read-back address points to something that does exist in the program. These generally don't crash right away and lead you away from the actual bug because the corruptor is sitting in another bit of code entirely whistling smugly as you blame and debug the wrong code. Either way accessing memory that has not been assigned to the pointer invokes Undefined Behaviour, and with UB anything can happen. Don't count on crashes or consistency.



        Generally you would use your operator << overloads to serialize the structure to the file rather than trying to binary write. If you have to do binary writes, you need to create a protocol that describes how data must be written and read.



        The protocol is going to be a set of functions that convert simpler data types to and from their file equivalents.



        A typical method for writing a string is to first write the length of the string and then write the contents of the string. Something like



        uint32 len = str.length(); //fixed width length
        len = htonl(len); // fixed endian
        myfile.write((char*) &len, sizeof(len)); //write length
        myfile.write(str.data(), str.length()); //write string


        And reading



        uint32 len; //fixed width length
        myfile.read((char*) &len, sizeof(len)); //read length
        len = ntohl(len); // unfix endian
        std::string str(len, ' '); //string and allocate size
        myfile.write(str.data(), len); //read string C++17 or
        //myfile.write(&str[0], len); //read string before C++17


        bundle these up inside functions and you've started on your protocol. Add to them functions for other data types you need to store.



        These functions are then called by functions that convert larger datatypes and on up until you reach the most complex of the structures you need to write. For an array, use a loop. If you have a length of variable size, prefix the length just like with a string.



        Side note: When reading or writing numbers care must be taken to ensure the number is a known, fixed size. int, for example, can be any size 16 bits or greater so long at it's not larger thanlong. You don't necessarily know that the file reader will be using the same sizedint`, so you should prefer a Fixed Width Integer large enough to store the values required. Different computers also may store their binary information in different orders. This is called Byte Order or Endian. Make sure everyone is using the same endian.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 at 2:58









        user4581301

        19.2k51831




        19.2k51831






























            draft saved

            draft discarded




















































            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384784%2ffile-i-o-binary-dynamic-array-crashed%23new-answer', 'question_page');
            }
            );

            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







            Popular posts from this blog

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            Refactoring coordinates for Minecraft Pi buildings written in Python