73

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

vector<int>* vecPtr;

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

int a = (*vecPtr)[i];

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

ありがとう!

4

2 に答える 2

89

10000int秒はコピーされません。逆参照は非常に安価です。

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

int a = (*vecPtr)[i];

なので

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

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

于 2009-12-15T22:10:14.287 に答える
54

いいえ、何もコピーされません。逆参照は、ポインタではなくベクトルでoperator[] を呼び出すことを C++ に伝えるだけです。逆参照しなかった場合、C++ は型で定義された operator[] を探します。vecPtrstd::vector<int>*

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

一般に、ポインターを介してベクトルにアクセスするのは面倒であり、(*vecPtr)[index]構文はぎこちなくなります (ただし、 よりはましですvecPtr->operator[](index))。代わりに、次を使用できます。

vecPtr->at(index)

とは異なり、これは実際に範囲operator[]をチェックするため、インデックスが境界内にあるかどうかをチェックするために代償を払いたくない場合は、 で立ち往生してい(*vecPtr)[]ます。

于 2009-12-15T22:10:29.790 に答える