0

I have a binary file which contains doubles of size of 8 bytes. I want to read the doubles into a vector<double>, see below

  ifstream infile("x.dat", ios::binary);
  vector<double>data(filesize/8, 0.0);
  for(int i=0; i< (filesize/8); ++i)
  {
    infile.read( (char *) (&data[i]), sizeof(double) );
  }

I know this would work if data was a C array, but not sure if this will work for vector, since vector contains more stuff than a C array(vector has methods), does the address &data[i] mean the address of the data member of the ith element?

Allanqunzi
  • 3,230
  • 1
  • 26
  • 58
  • 2
    Yes - the code's fine (apart from not checking `infile` for open/read errors). Why don't you run it, prove to yourself it works, and get on with the rest of the program? – Tony Delroy May 12 '15 at 06:08
  • 1
    `vector` is a sequential container hold data like `C` array with extra information like `size` and `capacity`. Yes it was also designed to be used as primitive arrays. – Fredrick Gauss May 12 '15 at 06:15
  • Possible duplicate of [Are std::vector Elements Guaranteed To Be Continuous](http://stackoverflow.com/questions/849168/are-stdvector-elements-guaranteed-to-be-contiguous). – Ami Tavory May 12 '15 at 06:16

1 Answers1

4

Yes, each vector element is just a double object, and &data[i] points to that object.

In fact, all the double objects are in a contiguous array, so you can read them all at once:

infile.read((char*)data.data(), filesize);

Of course, as noted below, this requires the file to have been written in a format compatible with your program's binary representation of double values, otherwise the values will be garbage.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • thanks, what does `data.data()` mean here? Does it return the address for the entire contiguous array of `double`s? – Allanqunzi May 12 '15 at 06:19
  • @Allanqunzi: Yes, it's the address of the first element of the array. It's the same as `&data[0]`. – Mike Seymour May 12 '15 at 06:20
  • 1
    @MikeSeymour The OP idea is in general not portable though, since the representation of doubles can vary across different OS (when dumped into files), isn't this so? – vsoftco May 12 '15 at 06:22
  • 1
    @vsoftco: It's as portable as the posted code. If the file was written out by a program using the same representation, then it's fine. It it used a different representation, then you'll get garbage. – Mike Seymour May 12 '15 at 06:23
  • @MikeSeymour, how about the iterators? if `vector::iterator it=data.begin()`, is `it==&data[0]` true? – Allanqunzi May 12 '15 at 06:31
  • 1
    @Allanqunzi: No, you can't compare an iterator with a pointer. But the address of the object it refers to, `&*it`, will be the same as `&data[0]`, since both are the address of the same object. – Mike Seymour May 12 '15 at 06:33
  • @MikeSeymour, yes, you are right, I just tested it. `it==&data[0]` doesn't compile. `&*it==&data[0]` works as what you said. This behavior is kind of counter intuitive. `it` and `&data[0]` are different things, but they point to the same address. – Allanqunzi May 12 '15 at 06:39
  • 1
    @Allanqunzi: It rather depends on your intuition. An iterator isn't a pointer (it just behaves like one in some ways), and in general you can't compare unrelated types; from that point of view, it's to be expected that you can't compare them. – Mike Seymour May 12 '15 at 06:42