简体   繁体   中英

Is casting a deque to and from void pointer safe?

The documentation says that

unlike vectors, deques are not guaranteed to store all its elements in contiguous storage locations

Does it mean that if I cast a deque to a void * and then back to the original deque I might end up with some random data inside?

No, it means that you can't take a deque's first element's address, cast it to a pointer, and then perform pointer arithmetics under the assumption that the rest of the elements are in continuous order:

deque<int> d;
//...
int* x = &(d[0]);
int secondElement = x[1]; // illegal 

vector<int> v;
//...
int* x = &(v[0]);
int secondElement = x[1]; // legal

You can cast a deque's address to a void* and cast it back with no worries though.

No. That's not what it means. First, you cannot cast a deque into void* . The two will have different sizes, and this will break the object.

What it actually means is that you can do:

vector<int> myVec = ...;
int* theBuffer = &myVec[0]; // In C++ 11, you can also do myVec.data() instead

And theBuffer will be a contiguous segment of memory, so you can pass it to a C function expecting a pointer for example (see below), access it using pointer arithmetic, etc. You cannot do this with a deque , as it's internal representation doesn't provide such guarantees. Note that this concerns itself with the data stored inside a vector or deque , not with the object itself. In case you'd like to store a pointer to a deque in a void* , you're free to do so.

// Example: A C function
extern "C" void a_c_function(int* data, const size_t num_elements);

// Invoking it on a vector's elements
a_c_function(&myVec[0], myVec.size());

You can't cast structures to pointers. reinterpret_cast might compile with some unknown semantics, but it's just asking for brokenness: a deque is going to be at least two pointers big, so it can't fit into one pointer.

You can cast a deque<…> * to a void * and back. This has nothing to do with the contents of the deque, but it's just taking the address of the container object itself.

std::deque< int > dq;

void * x = reinterpret_cast< void * >( dq ); // Nonsense.

void * y = static_cast< void * >( & dq ); // Type-erased ptr to object, OK.
std::deque< int > & dqr = * static_cast< std::deque< int > * >( y ); // restore type, OK.

The relevant difference between deque and vector is in their iterators : You can use a pointer to an element of a vector much the same as a vector::iterator because a vector uses contiguous storage. The only way to navigate through a deque is a deque::iterator , however.

int * vf = & vec.front(); // Ptr to first element
int * velem = vf + 10; // OK if vec has 10 elements.

int * df = & dq.front(); // Ptr to first element
int * delem = df + 10; // Error, although it might work sometimes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM