0

I am trying to read data from binary file, and having issues. I have reduced it down to the most simple case here, and it still won't work. I am new to c++ so I may be doing something silly but, if anyone could advise I would be very grateful.

Code:

int main(int argc,char *argv[]) {
    ifstream myfile;
    vector<bool> encoded2;

    cout << encoded2 << "\n"<< "\n" ;

    myfile.open(argv[2], ios::in | ios::binary |ios::ate );
    myfile.seekg(0,ios::beg);
    myfile.read((char*)&encoded2, 1 );
    myfile.close();


    cout << encoded2  << "\n"<< "\n" ;

}

Output

00000000

000000000000000000000000000011110000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Compression_Program(58221) malloc: * error for object 0x10012d: Non-aligned pointer being freed * set a breakpoint in malloc_error_break to debug

Thanks in advance.

1
  • What is a vector of encoded2 a std::vector<char> ? Use &encoded2[0] and resize your vector. Commented Feb 2, 2011 at 12:00

6 Answers 6

4

Do not cast a vector<bool>* to a char*. It is does not do anything predictable.

Sign up to request clarification or add additional context in comments.

Comments

1

You are reading on encoded2: myfile.read((char*)&encoded2, 1 );. this is wrong. you can to read a bool and then put it in encoded2

bool x;
myfile.read( &x, 1 );
encoded2[0] = x;

Comments

1

Two mistakes here:

  • you assume the address of a vector is the address of the first element
  • you rely on vector<bool>

Casting a vector into a char * is not really a good thing, because a vector is an object and stores some state along with its elements.

Here you are probably overwriting the state of the vector, thus the destructor of fails.

Maybe you would like to cast the elements of the vector (which are guaranteed to be stored contiguously in memory). But another trap is that vector<bool> may be implementation-optimized.

Therefore you should do a encoded2.reserve(8) and use myfile.read(reinterpret_cast<char *>(&encoded2[0])).

But probably you want to do something else and we need to know what the purpose is here.

6 Comments

I am basically writing a decompression program to take a block of binary data from a known part of the file, then convert this back to the correct form using the encoding. I therefore need to collect a large chunk of binary data. Does this change things?
Yes, but why do you use a vector of bools to store that binary data? Wouldn't a vector of char be better? In this way you will not have endianness problems.
@Benoit 1) Will not work, if vector is stored in bitmap 2) You must use 2 static_cast-s instead reinterpret_cast for such situations. reinterpret_cast is implementation defined operation.
I am using a vector of bools, because it is the output of a function that someone else wrote. Not sure if this is good or not, I am really new to c++ and still getting to grips with best practice.
I was just trying to do something like what is done here: courses.cs.vt.edu/~cs2604/fall02/binio.html under heading "Reading and Writing Complex Data"
|
1

You're overwriting a std::vector, which you shouldn't do. A std::vector is actually a pointer to a data array and an integer (probably a size_t) holding its size; if you overwrite these with practically random bits, data corruption will occur.

Since you're only reading a single byte, this will suffice:

char c;
myfile.read(&c, 1);

4 Comments

std::vector<bool> is bitmap array and not ordinary array. And it's size type is std::vector<bool>::size_type and not size_t
@larsmans yeah, but has different behavior than ordinary array(pointer[0] isn't first element anymore).
@Ashot: I know all that. The point that I'm trying to make is that the OP won't get correct behavior with any std::vector specialization by casting its address to char *. And yes, this is implementation-specific, but please describe any other sensible way of implementing std::vector that a C++ beginner can also understand.
I was just trying to do something like what is done here: courses.cs.vt.edu/~cs2604/fall02/binio.html under heading "Reading and Writing Complex Data"
1

The C++ language does not provide an efficient I/O method for reading bits as bits. You have to read bits in groups. Also, you have to worry about Endianess when reading int the bits.

I suggest the old fashioned method of allocating a buffer, reading into the buffer then operating on the buffer.

Allocating a buffer

const unsigned int BUFFER_SIZE = 1024 * 1024; // Let the compiler calculate it.
//...
unsigned char * const buffer = new unsigned char [BUFFER_SIZE];  // The pointer is constant.

Reading in the data

unsigned int bytes_read = 0;
ifstream data_file("myfile.bin", ios::binary); // Open file for input without translations.
data_file.read(buffer, BUFFER_SIZE); // Read data into the buffer.
bytes_read = data_file.gcount();  // Get actual count of bytes read.

Reminders:

  • delete the buffer when you are finished with it.
  • Close the file when you are finished with it.

Comments

0
myfile.read((char*) &encoded2[0], sizeof(int)* COUNT);

or you can use push_back();

int tmp;
for(int i = 0; i < COUNT; i++) {
  myfile.read((char*) &tmp, 4);
  encoded2.push_back(tmp);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.