web-dev-qa-db-ja.com

要素にアクセスするための逆参照ベクトルポインター

C++にベクターへのポインターがある場合:

vector<int>* vecPtr;

そして、私はベクトルの要素にアクセスしたいので、ベクトルを逆参照することでこれを行うことができます:

int a = (*vecPtr)[i];

しかし、この逆参照は実際にスタック上にベクターのコピーを作成しますか?ベクターに10000のintが格納されているとします。vecPtrを逆参照することで10000のintがコピーされます

ありがとう!

49
Mat

10000 intsはコピーされません。参照解除は非常に安価です。

明確にするために書き直すことができます

int a = (*vecPtr)[i];

として

vector<int>& vecRef = *vecPtr; // vector is not copied here
int a = vecRef[i];

さらに、vectorに格納されているデータ全体がスタックに配置されることを恐れている場合は、vector<int>* の代わりに vector<int>これを回避するには:これは当てはまりません。実際、スタックでは、vectorに格納されている要素の数に関係なく、固定量のメモリのみが使用されます(実装に応じて約16〜20バイト)。 vector自体がメモリを割り当て、要素をヒープに格納します。

59
sergtk

いいえ、何もコピーされません。デリファレンスは、C++にpointervecPtrではなく、vectorでoperator []を呼び出すことを伝えます。逆参照しなかった場合、C++は_std::vector<int>*_型で定義されたoperator []を探します。

_operator[]_がすべてのポインタータイプに対して定義されているため、これは非常に混乱する可能性がありますが、_vector<int>_の配列を指しているかのようにポインターをオフセットすることになります。実際に単一のベクトルのみを割り当てた場合、_0_以外のインデックスの場合、式はガベージへの参照と評価されるため、セグメンテーション違反または予期しない何かが発生します。

一般に、ポインターを介してベクターにアクセスするのは苦痛であり、_(*vecPtr)[index]_構文は厄介です(ただし、vecPtr->operator[](index)よりも優れています)。代わりに、次を使用できます。

_vecPtr->at(index)
_

_operator[]_とは異なり、これは実際に範囲をチェックするため、インデックスが範囲内にあるかどうかをチェックするための代価を払わない場合は、_(*vecPtr)[]_で止まってしまいます。

46
Todd Gamblin