言いましょう、私は持っています
int *p;
p = new int[5];
for(int i=0;i<5;i++)
*(p+i)=i;
次に、6番目の要素を配列に追加します。どうすればいいのですか?
配列を再割り当てしてデータをコピーする必要があります:
int *p;
p = new int[5];
for(int i=0;i<5;i++)
*(p+i)=i;
// realloc
int* temp = new int[6];
std::copy(p, p + 5, temp); // Suggested by comments from Nick and Bojan
delete [] p;
p = temp;
できません。このためには、STLベクターなどの動的コンテナーを使用する必要があります。または、より大きな別の配列を作成し、最初の配列からその配列にデータをコピーすることもできます。
その理由は、配列がメモリ内の連続した領域を表すためです。上記の例では、pがアドレス0x1000を指し、5つの整数が20バイトに対応しているため、配列が0x1014の境界で終了するとします。コンパイラは、0x1014から始まるメモリに他の変数を自由に配置できます。例えば、 int i
は0x1014..0x1018を占める場合があります。次に、配列を拡張してさらに4バイトを占有すると、どうなるでしょうか。
malloc
を使用して初期バッファーを割り当てる場合、realloc
を使用してバッファーのサイズを変更できます。 realloc
- edバッファーのサイズ変更にnew
を使用しないでください。
int * array = (int*)malloc(sizeof(int) * arrayLength);
array = (int*)realloc(array, sizeof(int) * newLength);
ただし、これはC風の方法です。 vector
の使用を検討してください。
どうしてvector
がソースを調べてみませんか?このメカニズムの実装は、C++インクルードファイルが存在するフォルダーで確認できます。
これはgcc 4.3.2で何をするかです:
ベクトルのアロケータを使用して、メモリの新しい連続したチャンクを割り当てます(ベクトルは_vector<Type, Allocator = new_allocator>
_?であることを覚えています)。デフォルトのアロケータはoperator new()
を呼び出して(new
!だけではありません)、このチャンクを割り当てます。これにより、_new[]
_/_delete[]
_のものをいじらないようになります。
既存の配列の内容を新しく割り当てられた配列にコピーします。
以前に整列されたチャンクをアロケーターで破棄します。デフォルトではoperator delete()
を使用します。
(独自のベクトルを作成する場合、サイズは「固定量」ではなく「M倍」に増加する必要があることに注意してください。これにより、一定の償却期間を達成できます。たとえば、サイズ制限。ベクトルが2倍になり、各要素は平均して1回コピーされます。)
他の人が言っているのと同じですが、配列のサイズを頻繁に変更する場合は、サイズを2倍にすることで、毎回配列のサイズを変更する方法があります。常に新しいものを作成し、古いものを破壊することには費用がかかるため、2倍化理論は、将来の要素にも十分な余地があることを保証することによって、この問題を軽減しようとします。