17

言ってみましょう、私は持っています

int *p;
p = new int[5];
for(int i=0;i<5;i++)
   *(p+i)=i;

次に、配列に 6 番目の要素を追加します。どうすればいいのですか?

4

5 に答える 5

32

配列を再割り当てし、データをコピーする必要があります。

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;
于 2009-08-29T06:22:23.417 に答える
11

それはいけません。これには、STL ベクトルなどの動的コンテナーを使用する必要があります。または、より大きな別の配列を作成し、最初の配列からデータをコピーすることもできます。

その理由は、配列がメモリ内の連続した領域を表すためです。上記の例では、p がアドレス 0x1000 を指し、5 つの int が 20 バイトに対応するため、配列は 0x1014 の境界で終了するとします。コンパイラは、0x1014 から始まるメモリに他の変数を自由に配置できます。たとえば、int i0x1014..0x1018 を占める場合があります。さらに 4 バイトを占有するように配列を拡張すると、どうなるでしょうか?

于 2009-08-29T06:23:18.500 に答える
3

を使用して初期バッファを割り当てると、mallocを使用reallocしてバッファのサイズを変更できます。-ed バッファーreallocのサイズ変更には使用しないでください。new

int * array = (int*)malloc(sizeof(int) * arrayLength);
array = (int*)realloc(array, sizeof(int) * newLength);

ただし、これは C っぽいやり方です。の使用を検討する必要がありますvector

于 2009-08-29T06:21:50.750 に答える
2

ソースを調べてみませんvectorか?このメカニズムの実装は、C++ インクルード ファイルが存在するフォルダーで確認できます。

gcc 4.3.2 での動作は次のとおりです。

  1. ベクターのアロケーターを使用して、新しい連続したメモリのチャンクを割り当てます (ベクターが ? であることを覚えていvector<Type, Allocator = new_allocator>ます)。デフォルトのアロケータはoperator new()(! だけでなくnew) このチャンクを割り当てるために呼び出しnew[]ますdelete[]

  2. 既存の配列の内容を新しく割り当てられた配列にコピーします。

  3. 以前に整列されたチャンクをアロケータで破棄します。デフォルトのものは を使用しますoperator delete()

(独自のベクトルを作成する場合、サイズは「固定量」ではなく「M 倍」に増加する必要があることに注意してください。これにより、償却された定数時間を達成できます。たとえば、サイズ制限により、ベクトルが 2 倍になり、各要素が平均して 1 回コピーされます。)

于 2009-08-29T08:56:50.250 に答える
1

他の人が言っているのと同じですが、配列のサイズを頻繁に変更する場合、1 つの戦略はサイズを 2 倍にして毎回配列のサイズを変更することです。常に新しいものを作成し、古いものを破壊するには費用がかかるため、倍増理論では、将来の要素にも十分な余地を確保することで、この問題を軽減しようとします。

于 2009-08-29T06:24:40.633 に答える