3
#include <bits/stdc++.h>

using namespace std;

class student
{
 string name;
 string reg;
public:
 void getdata()
 {
  getline(cin,name);
  getline(cin,reg);
 }
 void printdata()
 {
  cout<<name<<"\t"<<reg<<endl;
 }
};

int main()
{
 ifstream fin;
 ofstream fout;
 student obj;
 fout.open("google.txt",ios::out|ios::binary);
 obj.getdata();
 fout.write((char*)&obj,sizeof(obj));
 fout.close();
 student obj2;
 fin.open("google.txt",ios::in|ios::binary);
 fin.read((char*)&obj2,sizeof(obj2));
 obj2.printdata();
 fin.close();
 return 0;
}

I am trying a basic read and write operation of file handling of objects. But after executing the above code I am successfully able to write and read but I get an error message *** Error in ./io: free(): invalid size: 0x00007ffea93f64b0 ***Aborted (core dumped)

Input: Fire Blade , 17HFi394 Output:
Fire Blade , 17HFi394 and an error message : *** Error in ./io: free(): invalid size: 0x00007ffea93f64b0 ***Aborted (core dumped) Can anyone explain this error and what should I do to overcome this problem.

ankit
  • 324
  • 1
  • 4
  • 11
  • You don't like the say a string gets written to a binary file. Consider a text file to get ahead, "google.txt" is a good hint that is what you actually want. – Hans Passant Mar 22 '18 at 07:17
  • Unrelated: Be careful with `#include `. It is an internal implementation header for the g++ compiler and not intended to be used by user code. It also includes pretty much the entire C++ Standard Library. That's a lot of stuff you probably aren't using. Combine that with `using namespace std` and you've dropped a thousands of identifiers into the global namespace where it can easily conflict with your code. Most of the time you'll probably be just fine, but you can get weird compiler errors if you're lucky and strange program behaviour if you aren't. – user4581301 Mar 22 '18 at 07:38
  • @user4581301 Thanks . I will keep this in mind – ankit Mar 22 '18 at 08:18

2 Answers2

4

The problem is because you write a raw std::string object to a file, and then read it again. That leads to undefined behavior.

This doesn't work because a std::string is basically (and simplified) just a pointer to the actual string data. When you write the string object, you write the pointer, and when you read the object back from the file, you read the pointer. The problem is that now you have two string object both pointing to the same data. When the first object goes out of scope and is destructed, it will free the string data, leaving the other object with an invalid pointer to data that is no longer owned by your process. When that second object is destructed it will try to free the already free'd data.

And this is only when you save and load the object in a single process. It's even worse if you attempted to load the object in a different process (even if it's the same program), and for modern virtual memory system no two process have the same memory maps.

To save data to a file you should do research about serialization.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Can you give a quick suggestion how to overcome this problem in the above code. – ankit Mar 22 '18 at 07:38
  • @ankit Not really since I don't know the use-case or the problem you want the code to solve. However, to begin with you could write the class to a text-file using normal formatted output and input, or `std::getline` or similar functionality. – Some programmer dude Mar 22 '18 at 07:43
0

std::string size is variable, try the following code:

```

char name[256];
char reg[256];

void getdata()
{
    std::cin.getline(name, sizeof(name));
    std::cin.getline(reg, sizeof(reg));
}

```

tujiaw
  • 81
  • 3