reinterpret_cast error

I'm experimenting with some binary files lately. Oh, I hear you out there: "Binary files...wtf?" But I'm trying to create a sort of database, and I'm getting this weird error.

So, I have a class Customer, and I'm trying to store a vector of Customers in the binary file, and then read them out. The Customer class is all C-strings (ugh), and it has no other errors in it.

My OS is macOS X High Sierra, and my compiler is LLVM clang 10.

The Code:
1
2
// read customers into vector for checking
	incustomerfile.read ((reinterpret_cast <char*> (&customerList), customerList.size());


The Error:
:24: error: reinterpret_cast from 'const std::vector<Customer> *' to 'char *' casts away qualifiers
        incustomerfile.read ((reinterpret_cast <char *> (&customerList), customerList.size());
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


If you need more code, let me know and I'll be glad to post more; but be warned, there's a total of one 400-line header file, one 75-line header file, one 200-line header file, one 350-line header file, and a 7-line driver program.

Any help is appreciated!
Thanks!
max
reinterpret_cast <char*> (&customerList[0]) (I'm not sure if reinterpret_cast is the right cast for this.)
Writing to an std::vector<T> as if it was a raw block of memory would almost certainly lead to undefined behavior by overwriting its internal pointer to the data.
Hmm. What would you suggest I use instead?

Oh, I think I've seen something like this somewhere, and I just remembered. It was something like a class derived from a vector, and it used something like this to read in from a file.

Would that work?

Or, I just had another thought, what if I tried just reading the values from the vector, individually storing them in the file, and then vice versa for reading from the file?

I'm using a vector because I want it to be expandable.

Yeah, I think I'll try my second idea, and if it doesn't work, I'll post back.
Have you looked at what the Boost libraries have to offer?

A quick perusal of the documentation shows there are two libraries you could look at using to leverage serialization.

JSON:
https://www.boost.org/doc/libs/1_75_0/libs/json/doc/html/json/overview.html

Serialization:
https://www.boost.org/doc/libs/1_75_0/libs/serialization/doc/index.html

I haven't really used either library much or recently, so the suitability of either I can't address with any confidence.
Hmm. I'll check them out, thanks!

I might actually have that already...do you know of any specific header files I can try #include-ing to test?
Read the docs I linked, and get the latest Boost version. There are examples/demos available for either library.

Since you want to use std::vectors to contain your data the Serialization library might be your best bet.

FYI, parts of previous Boost versions have been added to the C++ standard library. A couple of biggies are random number generation and smart pointers.

C++20 has C printf style formatting, Boost introduced something similar back in 2002.

If you use only one set of 3rd party libraries, consider Boost.
Furry Guy's suggestion notwithstanding, I don't think you quite got the gist of my post.
You wrote reinterpret_cast<char *>(&customerList), and my correction was reinterpret_cast<char *>(&customerList[0]). Do you understand why that "[0]" is so important?
helios,
Oops, I didn't even notice that! I thought you were quoting me. But no, I'm afraid I don't. Do you mean that it has to be a single element of the vector instead of the entire vector?

Because I tried this:
1
2
3
4
5
while (!customerFile.eof())
{
    customerFile.read (reinterpret_cast <char*> (&tempCustomer), sizeof (tempCustomer));
   customerList.push_back (tempCustomer);
}

where tempCustomer is an object of the Customer class.

It seemed to work– it got rid of the error, at least.

Furry Guy,
Hmm. Is Ncurses similar to Boost? Because I actually already have that, as I noted in the "<windows.h> header file" topic. So I wouldn't need to download anything.
Last edited on
I mean what you intended to do initially, which was to read from the file in one go by writing to the vector as if it was an array is accomplished with my correction. Since a vector's internal structure is basically
1
2
3
4
5
6
template <typename T>
class vector{
    T *data;
    size_t size;
    size_t capacity;
};
when you do file.read((char *)&vector, /*...*/) you're corrupting the vector by overwriting its internal pointer and lengths. By instead doing file.read((char *)&vector[0], /*...*/) you write to the vector's internal array. vector[0] gives you a reference to the vector's first element, and the address-of operator gets you its address, which is the same as the internal array's address.
Ncurses is nothing like Boost. Two completely different libraries.
helios,
Oh! Ok, that makes sense. Will what I did work as well, or do I need to change my program again?

Furry Guy,
Dang. Welp, I'll look into downloading it.

Thanks!
Topic archived. No new replies allowed.