Pointer to vector's array

Started by
8 comments, last by SiCrane 13 years, 4 months ago
C++ I know you can get a pointer to a vector's internal array, but is this ever a good idea? Is it safe? (so long as you don't go out of bounds ofc) Is it cross-platform?
Advertisement
Depends on what you mean by "getting a pointer to the vector's internal array". The 2003 revision of the C++ standard, which is the current version, does guarantee that vector elements are allocated contiguously, if that's what you're asking. However, it wasn't guaranteed by the previous version.
Getting at a vector's internal storage really only makes sense when you really NEED to have access to that array, i.e. for instance when working with old C API's with functions taking plain C-style arrays. In any other case you're better off just passing the vector object itself.
Quote:Original post by CzarKirk
C++ I know you can get a pointer to a vector's internal array, but is this ever a good idea? Is it safe? (so long as you don't go out of bounds ofc) Is it cross-platform?
Assuming a modern, standard-conformant implementation of the standard library, the answer is basically, yes it's safe (as long as you don't do anything unsafe ;), it's as 'cross-platform' as C++ itself is (IINM), and it's a 'good idea' whenever it's the only and/or best way to solve the problem at hand.

Where this is most commonly done (IMX) is when you're working with an API that expects a raw array or pointer. For example, it's pretty common to store model data (vertices, normals, etc.) in a vector, and then pass the address of the underlying storage to API functions that expect a raw pointer to that data.

Providing the implementation is conformant, the data is guaranteed to be contiguous (as no such user said). Just be aware that the pointer can become invalid under the same circumstances that iterators can become invalid, so in general, you won't want to store the pointer. (Again, typical usage would be to pass the address to an API function that expects a raw pointer, but not to store the pointer and re-use it later.)
Yes that is similar to what I'm doing. Merging some old C style code and new code. To get things going again quickly I wanted to use vectors to manage the memory of an array instead of dynamic, and use a pointer to the internal array when required by the old code.

Crazy question - if I have a vector of char, can I use this as a back end data store and cast a pointer to another data type to it? So make the vector big enough to hold n structs of arbitrary type, and then cast a struct * pointer to the beginning of the array, and use it as an array of the struct?
A char vector may not be properly aligned for storing other types. Depending on your platform this may be either unnoticeable, have a small performance overhead or bus lock your program.
Hi no such user, could you please elaborate? I am not very familiar with that topic. Thank you.
All memory addresses are not equal when it comes to storing data. If, for instance, you have a four byte data type you generally want to store that data at a memory address that is a multiple of four. This kind of restriction on memory address is called the alignment of data. Depending on the platform, and sometimes the operation, what happens when you deal with unaligned data varies. On x86, reading or writing unaligned data usually only results in a few extra clock cycles of overhead. If the unaligned data spans cache lines or memory pages then it can be quite a bit more than a few clock cycles. However, some platforms outright will not read or write unaligned data and trying will bring up some sort of hardware error. This can also happen on x86 with certain operations like SSE.

For a std::vector<char>, the memory allocated is only guaranteed to be aligned properly for a char, and since char is one byte, this often means that it is not guaranteed to be aligned for pretty much anything else. If you want to store something other than a char in that location then a variety of bad things can happen. Depending on your compiler and standard library implementation, std::vector<char>'s data may have some sort of alignment beyond that necessary for a char, but in standard C++, nothing is guaranteed.
How is this different to requesting a chunk of memory from malloc and using it to hold structures?
malloc() is guaranteed to return a memory block properly aligned for any standard type. (It may not be aligned for non-standard types like MSVC's __m128.) However, there is no such guarantee for using the data stored by by std::vector<char>. If the underlying allocator uses malloc() internally or something similar, then you may be able to get away with it, but then you're relying on implementation details and your code may not be portable. In particular frame based allocators are more likely to give you unaligned data when you request chars than if you request larger data types.

This topic is closed to new replies.

Advertisement