是否安全地从无效指针中插入双端队列?

时间:2014-05-14 08:55:17

标签: c++ stl

文档说明

  

与矢量不同,deques不能保证将其所有元素存储在连续的存储位置

这是否意味着如果我将一个双端队列转移到一个空格*然后回到原始的双端队列,我可能会在里面找到一些随机数据?

3 个答案:

答案 0 :(得分:10)

不,这意味着您无法获取deque的第一个元素的地址,将其转换为指针,然后在假设其余元素为的情况下执行指针算术按顺序排列:

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

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

你可以将一张deque的地址投射到void*并将其丢回,但不用担心。

答案 1 :(得分:1)

没有。这不是它的意思。首先,您无法deque投射到void*。这两个将有不同的大小,这将打破对象。

它实际意味着你能做到:

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

并且theBuffer将是一个连续的内存段,因此您可以将其传递给期望指针的C函数(例如,见下文),使用指针算法访问它等。 您无法使用deque执行此操作,因为它的内部表示不提供此类保证。请注意,这与存储在vectordeque内的数据有关,而与对象本身无关。如果您想在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());

答案 2 :(得分:0)

您无法将结构强制转换为指针。 reinterpret_cast可能会使用一些未知的语义进行编译,但它只是要求破解:deque将至少有两个指针,因此它不能适合一个指针。

您可以将deque<…> *投射到void *并返回。这与deque的内容无关,但它只是取容器对象本身的地址。

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.

dequevector之间的相关区别在于它们的迭代器:您可以使用指向vector元素的指针与vector::iterator因为向量使用连续存储。然而,浏览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.