简体   繁体   English

在空指针上进行双向穿刺是否安全?

[英]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? 这是否意味着如果我将双端队列强制转换为void *,然后又回到原始双端队列,则可能最终会在其中包含一些随机数据?

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. 您可以将双端队列的地址转换为void* ,然后无后顾之忧地将其返回。

No. That's not what it means. 不,那不是什么意思。 First, you cannot cast a deque into void* . 首先,您无法deque投放到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. 并且theBuffer将是一个连续的内存段,因此您可以将其传递给需要指针的C函数(例如,参见下文),使用指针算法进行访问,等等。您不能使用deque进行此操作,因为deque的内部表示没有不提供此类保证。 Note that this concerns itself with the data stored inside a vector or deque , not with the object itself. 请注意,这本身与存储在vectordeque数据有关 ,而与对象本身无关。 In case you'd like to store a pointer to a deque in a void* , you're free to do so. 如果您想将指向deque的指针存储在void* ,则可以随意这样做。

// 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. reinterpret_cast可能会使用一些未知的语义进行编译,但是它只是要求破译: deque至少要有两个指针大,因此不能容纳一个指针。

You can cast a deque<…> * to a void * and back. 您可以将deque<…> *转换为void *并返回。 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. dequevector之间的相关区别在于它们的迭代器 :您可以使用指向vector元素的指针,该指针与vector::iterator几乎相同,因为向量使用连续存储。 The only way to navigate through a deque is a deque::iterator , however. 但是,唯一一种在deque导航的方法是deque::iterator

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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