C++でrealloc
を使用するにはどうすればよいですか?言語にはないようです-new
とdelete
がありますが、resize
はありません!
私のプログラムがより多くのデータを読み込むにつれて、それを保持するためにバッファを再割り当てする必要があるため、それが必要です。古いポインターをdelete
ingし、新しい大きなポインターをnew
ingするのは正しい選択肢ではないと思います。
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++コードです。
おそらく、std::vector
のように、作業を行うコンテナを使用するのが適切なオプションです。
new
およびdelete
は、指定されたタイプのオブジェクトを保持するのに十分なメモリを割り当てるため、サイズを変更できません。特定のタイプのサイズは変更されません。 new[]
とdelete[]
がありますが、それらを使用する理由はほとんどありません。
Cでrealloc
が行うことは、とにかくmalloc
、memcpy
、およびfree
である可能性がありますが、メモリマネージャーは、もしあれば十分な連続した空きメモリが利用可能です。
C++でのサイズ変更は、コンストラクターとデストラクターを呼び出す必要があるため、扱いにくいです。
C++で_resize[]
_および_new[]
_と一緒に使用する_delete[]
_演算子を使用できなかった根本的な理由はないと思います。
_newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;
_
明らかにoldsize
は秘密の場所から取得されます。これは_delete[]
_にあり、Type
はオペランドの型から取得されます。 _resize[]
_は、Typeがコピー可能でない場合に失敗します-そのようなオブジェクトは単に再配置できないため、正しいです。最後に、上記のコードは、オブジェクトを割り当てる前にデフォルトで構成しますが、これは実際の動作としては望ましくありません。
_newsize <= oldsize
_を使用して、新しく縮小された配列の「最後を過ぎた」オブジェクトのデストラクタを呼び出し、それ以外は何もしない最適化が可能です。標準では、この最適化が必要か(resize()
ベクトルの場合)、許可されているが指定されていない、許可されているが実装依存、または禁止されるかを定義する必要があります。
次に、あなた自身に問うべき質問は、「vector
が提供することを考えると、実際にこれを提供することは有用であり、特に連続メモリのサイズ変更可能なコンテナを提供するように設計されています。 C++ 98ですが、C++ 03で修正されました)これは、C++の方法で配列よりも適していますか?」
答えは広く「いいえ」と考えられていると思います。 Cの方法でサイズ変更可能なバッファーを使用する場合は、C++で使用可能な_malloc / free / realloc
_を使用します。サイズ変更可能なバッファをC++の方法で処理する場合は、ベクトルを使用します(実際に連続したストレージが必要ない場合はdeque
を使用します)。ベクトルのようなコンテナを実装している場合を除き、生のバッファに_new[]
_を使用して2つを混合しようとしないでください。