0

Alright, I'm a bit new to this so apologies if my question seems stupid.

Basically, I'm trying to read from a binary file into a string.
The code:

using namespace std;
fstream words;
words.open("Data/words.bin", ios::binary | ios::in);
string s;
words.read((char*)&s, sizeof(string));
cout << s;
words.close();

Compiling this gives me the following error:
Unhandled exception at 0x0FABDF58 (msvcp120d.dll) in HangMan.exe: 0xC0000005: Access violation reading location 0x052DE6EC.

However it does print the string to the console before throwing up the error.

Writing to the file does not result in any sort of error though nor does reading a char[]. The problem only occurs when reading into a string.

EDIT:

I kind of knew that it isn't a good idea to cast string* to char* but I understand now. Its just that following code works, so I assumed using a string would also work:

#include <string>
#include <fstream>
#include <iostream>
using namespace std;

class foo
{
private: 
int X;
int Y;
int Z;
char C;
public:
    foo(int x,int y,int z, char c): X(x), Y(y), Z(z), C(c){}

void display()
    {
        cout<<X<<endl<<Y<<endl<<Z<<endl<<C<<endl;
    }
};

int main()
{
    fstream out;
    out.open("file.bin", ios::binary | ios::out);
    foo var(1,2,3,'a');
    out.write((char*)&var,sizeof(foo));
    cout<<"var: \n";
    var.display();
    out.close();
    cout<<"var2 before reading: \n";
    foo var2(0,0,0,'z');
    var2.display();
    fstream in;
    in.open("file.bin", ios::binary|ios::in);
    in.read((char*)&var2,sizeof(foo));
    cout<<"var2 after reading: \n";
    var2.display();
    return 0;

}

If I understand right, this shouldn't work either correct?

@Rakibul Hasan: I checked both the questions, not a duplicate.

user3690467
  • 3,049
  • 6
  • 27
  • 54
  • how compiling can give any error? – Rakib May 30 '14 at 08:16
  • "Writing to the file does not result in any sort of error though..." - honestly, if this code is how you're trying to read it, I wouldn't bet the farm that statement about writing is true without seeing it. You may want to post *both* operations (preferably in an [SSCCE](http://www.sscce.org)). – WhozCraig May 30 '14 at 08:25

2 Answers2

1

You are casting a string* to char*, which is invalid.

Rakib
  • 7,435
  • 7
  • 29
  • 45
  • I'm casting the address to char*. This works fine for other data types. If I replace every mention of "string" with "int". This exact code works flawlessly (given the file exists). – user3690467 May 30 '14 at 08:24
  • if casting works fine, then it is by chance. `char*` and `string` are two totally different things and *string->char** is invalid. You can use the *char** contained in a `string` though, like `s.c_str()`. – Rakib May 30 '14 at 08:26
  • 1
    @user3690467 You're casting a non POD-type to a raw pointer and blasting over its in-memory data image. Its *undefined behavior* to do so. – WhozCraig May 30 '14 at 08:26
  • Note that as OP poited out, he's actually casting a `string*` to `char*`. Which is of course also invalid. – eerorika May 30 '14 at 08:36
1

Casting from string to char* is a very bad idea:

string s;
words.read((char*)&s, sizeof(string));

You need to allocate memory first. If you want to read file in one shot (only for small files):

size_t fileSize = words.seekg( 0, std::ios::end ).tellg() - words.seekg( 0 ).tellg();
std::vector<char> buf( fileSize );

words.read( &buf[0], buf.size() );
Ivan
  • 2,007
  • 11
  • 15
  • I understand. I added some code to the OP. Basically if I create a class myself and cast customclass* to char* in much the same way, the program writes and reads from file flawlessly. But it shouldn't.. If I'm not mistaken, would like to know why it does work! – user3690467 May 30 '14 at 10:10