Raw pointers or vectrors?

I am trying to avoid using raw pointers as much as possible. However, here is a scenario where I can't think of an elegant way to avoid it.

I have a binary file that has stored a list of ints. The size is unknown at design time. So I would new up an array of ints, give the pointer to fstream::read() to read the whole block into the memory. When I am done with the data, I would delete the pointer.

Ideally, I would use a vector of ints to represent the data so that it's exception safe, and I don't have to worry about memory management. But then, I would need to read one int at a time from the file, which isn't efficient nor elegant.

Any suggestions?
You can specify the size of the vector in the constructor or by calling resize. You can then pass &vec[0] to the read function. In C++11 you can use vec.data() instead.
Last edited on
... or you can preallocate enough space in the vector with reserve(), then use push_back() to add each entry.
Thanks! So is it guaranteed that the elements of the vector will occupy a continuous chunk of memory? What if the size of the element (e.g. 4-byte integer, or an odd size struct) is not a multiply of the byte alignment?
If you use resize() or reserve() you're guranteed a contiguous block of memory <edit>that won't change</edit>.
Last edited on
The underlying implementation of a vector is always** guaranteed to be a contiguous block of memory, no matter what you do to it. If you declare your vector as std::vector<unsigned char> and treat it as a byte array, then the type/size of the data you actually store in it (whether its a struct, int, etc) will be irrelevant so long as it actually fits within the size you've allocated.

You can do a reinterpret_cast to overlay any kind of pointer interface of your choosing, and this will ensure that copying in/out of the byte buffer works for that particular type.

e.g.
1
2
3
4
5
6
7
8
9
 static const size_t howmany = sizeof(int) * 10;

// define its size and fill it up with lots of zero bytes
std::vector<unsigned char> bytes( howmany, '\0' );

int* begin = reinterpret_cast<int*>( &bytes[0] );
int* end = reinterpret_cast<int*>( &bytes[0] + howmany );

std::vector<int> numbers( begin, end ); 


in this particular case I wouldn't suggest using 'reserve', because you almost certainly want your vector::size() to return the number of bytes that you're actually using. Specifying the size as part of the constructor call, or using resize would be most appropriate IMO.



** "always" - unless you do something "weird" like define your own replacement for std::allocator or overload the new operator, then you could stop it from being stored contiguously - but if you were doing that, then you'd probably not be here asking that question :)
Last edited on
Topic archived. No new replies allowed.