90

reallocC++ でどのようにすればよいですか? それは言語に欠けているようです - newandはありますdeleteが、ありませんresize!

プログラムがより多くのデータを読み取ると、それを保持するためにバッファーを再割り当てする必要があるため、これが必要です。delete古いポインターを使用しnewて新しい、より大きなポインターを使用することは正しい選択肢ではないと思います。

4

4 に答える 4

58

::std::vector を使用してください!

Type* t = (Type*)malloc(sizeof(Type)*n) 
memset(t, 0, sizeof(Type)*m)

になる

::std::vector<Type> t(n, 0);

それで

t = (Type*)realloc(t, sizeof(Type) * n2);

になる

t.resize(n2);

ポインターを関数に渡したい場合は、代わりに

Foo(t)

使用する

Foo(&t[0])

vector はスマート C 配列であるため、これは完全に正しい C++ コードです。

于 2010-08-14T11:11:56.600 に答える
53

適切なオプションは、おそらく のように作業を行うコンテナーを使用することですstd::vector

newdelete指定されたタイプのオブジェクトを保持するのに十分なメモリを割り当てるため、サイズを変更できません。特定のタイプのサイズは変更されません。ありますがnew[]delete[]それらを使用する理由はほとんどありません。

とにかく、C で行うことは単に, andでreallocある可能性が高いですが、十分な連続した空きメモリが利用可能である場合、メモリ マネージャは巧妙なことを行うことができます。mallocmemcpyfree

于 2010-08-14T10:42:06.273 に答える
41

C ++でのサイズ変更は、コンストラクタとデストラクタを呼び出す必要がある可能性があるため、厄介です。

resize[]C ++で演算子を使用できないという根本的な理由はないと思いますが、これは次のようなことをしましたnew[]delete[]

newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;

明らかにoldsize、秘密の場所から取得されます。これは、にあるのと同じでdelete[]ありType、オペランドの型から取得されます。resize[]タイプがコピーできない場合は失敗します-そのようなオブジェクトは単に再配置できないため、これは正しいです。最後に、上記のコードはデフォルトで、オブジェクトを割り当てる前にオブジェクトを構築します。これは、実際の動作としては望ましくありません。

newsize <= oldsize新しく縮小された配列の「終わりを過ぎて」オブジェクトのデストラクタを呼び出し、他に何もしないという最適化の可能性があります。標準では、この最適化が必要か(resize()ベクトルの場合のように)、許可されているが指定されていないか、許可されているが実装に依存しているか、禁止されているかを定義する必要があります。

次に、自分自身に問いかける必要があります。「これを提供することは実際に役立ちます。これvectorも同様に機能し、サイズ変更可能なコンテナ(連続メモリの-C ++ 98では要件が省略されていますが)を提供するように特別に設計されています。 C ++ 03で修正されました)これは、C ++の方法で配列を実行するよりも適していますか?」

答えは「ノー」だと広く考えられていると思います。サイズ変更可能なバッファをCの方法で実行する場合malloc / free / reallocは、C++で使用可能なを使用します。サイズ変更可能なバッファをC++の方法で実行する場合は、ベクトルを使用します(またはdeque、実際に連続したストレージが必要ない場合は)。new[]ベクトルのようなコンテナを実装している場合を除いて、rawバッファに使用して2つを混合しようとしないでください。

于 2010-08-14T12:36:58.557 に答える