Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use fread() on a binary file to read the data into a std::vector?

Follow-up question on an earlier question I had, that has been perfectly answered. To quickly recap, I had trouble creating a class holding a huge array (stack overflow error). In the answers, some users recommended I use std::vector instead.

The function to read in the data looks like this:

Test()
{
   memset(myarray, 0, sizeof(myarray));
   FILE* fstr = fopen("myfile.dat", "rb");
   size_t success= fread(myarray, sizeof(myarray), 1, fstr);
   fclose(fstr);
}

for a myarray which looked like this:

int myarray[45000000];

My question is: How can I read this into a preferable:

std::vector<int> myvector;

I searched google , and have found multiple answers, usually pointing to the following code:

std::ifstream input("myfile.dat", std::ios::in | std::ifstream::binary);
std::copy(std::istream_iterator<int>(input), 
     std::istream_iterator<int>(), 
     std::back_inserter(myvector));

After implementing this, and when calling myvector.size() I get 16 (for whatever reason), and accessing a vector element leads to an immediate crash for going out of the vector bounds.

So what do I have to do to get this right? I once read somewhere that I could just simply use the "old" method, and then reading the array into the vector, but this seems to defeat the purpose of using the vector in the first place.

like image 816
Mark Anderson Avatar asked Dec 27 '22 08:12

Mark Anderson


1 Answers

fread() reads your file binary, while ifstream_iterator tries to extract formatted ints (like 42).

You want to resize your vector and use input.read(...) instead:

const size_t size = 45000000; // change this to the appropriate value
std::vector<char> myvector(size, 0);
std::ifstream input("myfile.dat", std::ios::in | std::ifstream::binary);
input.read(&myvector[0], myvector.size());

Note that you need to use a std::vector<char> since read expects the first parameter to be a char *. You can use other types T if you cast the type correctly:

input.read(reinterpret_cast<char*>(&myvector[0]), myvector.size() * sizeof(T));
like image 200
Zeta Avatar answered May 04 '23 07:05

Zeta