サイズ変更されたSTLベクトルがある場合、要素0のアドレスを取得し、ベクトルの残りの部分がメモリ内で続くと想定しても安全ですか?
例えば
vector<char> vc(100);
// do some stuff with vc
vc.resize(200);
char* p = &vc[0];
// do stuff with *p
はい、それは有効な仮定です (*)。
C++03 標準 (23.2.4.1) から:
ベクトルの要素は連続して格納されます。つまり、T が bool 以外の型の場合、v がベクトルである場合、すべての 0 <= n < v に対して恒等式 &v[n] == &v[0] + n に従います。 。サイズ()。
(*) ... ただし、配列に要素を追加した後、配列が再割り当てされる (ポインターとイテレーターが無効になる) ことに注意してください。
C++03 標準では、ベクトル要素が連続している必要があることを明確にするために文言が追加されました。
C++03 23.2.4 パラグラフ 1 には、C++98 標準ドキュメントにない次の言語が含まれています。
a の要素は
vector
連続して格納されます。つまり、が以外の型でv
ある 場合、すべての の同一性に従います。vector<T, Allocator>
T
bool
&v[n] == &v[0] + n
0 <= n < v.size()
Herb Sutter は、彼のブログ エントリの 1 つで、この変更について語っています。
...連続性は、実際にはベクトル抽象化の一部です。実際、C++98 標準が連続性を完全に保証していないことが判明したとき、C++03 標準が修正され、明示的に保証が追加されたほど重要です。
ストレージは常に連続していますが、ベクターの容量が変更されると移動する可能性があります。
容量変更操作の前に要素 0 (または任意の要素) にポインター、参照、または反復子があった場合、それらは無効になり、再割り当てする必要があります。
std::vector
アイテムが連続した配列に格納されることを保証するため、配列の代替として推奨され、プラットフォームに依存する低レベル コード (Win32 API 呼び出しなど) とのインターフェイスにも使用できます。配列へのポインターを取得するには、次を使用します。
&myVector.front();
はい。
常に隣接している必要があります