The standard requires that you can create an array of type struct. When you do this, the array should be contiguous. This means that no matter what size is allocated for the structure, it should be one that allows you to create an array of them. To ensure that the compiler can allocate additional space within the structure, but cannot require additional space between structures.
The space for data in vector (usually) is allocated ::operator new (through the Allocator class), and ::operator new needs to allocate space that is correctly aligned for any type of storage.
You can provide your own Allocator and / or overload ::operator new , but if you do, your version is still required to meet the same requirements, so nothing will change in this regard.
In other words, exactly what you want should work as long as the data in the file was created in much the same way as you are trying to read it. If it was created on another machine or using another compiler (or even the same compiler with different flags) you have many potential problems - you may get differences in content, filling in the structure, etc.
Change Given that you do not know if the structures were written in the format expected by the compiler, you not only need to read the structures one at a time - you really need to read the elements in the structures one at a time, then put them into a temporary struct and finally add this filled struct into your collection.
Fortunately, you can overload operator>> to automate most of this. This does not improve speed (for example), but may contain a cleaner code:
struct whatever { int x, y, z; char stuff[672-3*sizeof(int)]; friend std::istream &operator>>(std::istream &is, whatever &w) { is >> wx >> wy >> wz; return is.read(w.stuff, sizeof(w.stuff); } }; int main(int argc, char **argv) { std::vector<whatever> data; assert(argc>1); std::ifstream infile(argv[1]); std::copy(std::istream_iterator<whatever>(infile), std::istream_iterator<whatever>(), std::back_inserter(data)); return 0; }
Jerry Coffin
source share