C ++コードでのrealloc実装の使用に関する質問
-
06-07-2019 - |
質問
友達
C ++では、Iallocはreallocメソッドを使用してmallocによって割り当てられたメモリのサイズを変更します。 realloc()の使用方法は次のとおりです
my_Struct *strPtr =(my_struct*)malloc(sizeof(my_Struct));
/* an later */
strPtr = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);
現在wikipeadia(_http://en.wikipedia.org/wiki/Malloc)は次のように述べています
代わりにした場合
void *p = malloc(orig_size);
/* and later... */
p = realloc(p, big_size);
その後、big_sizeバイトのメモリを取得できない場合、pの値はNULLになり、以前にpに割り当てられたメモリへのポインタがなくなり、メモリリークが発生します
また、上記のエラーを修正する正しい方法は
void *p = malloc(orig_size);
/* and later... */
void *tmp = realloc(p, big_size);
if (tmp != NULL)
{
p = tmp; /* OK, assign new, larger storage to p */
}
else
{
/* handle the problem somehow */
}
realloc()を使用する最適な方法を教えてください
また、一度構造体へのポインタを取得してから、後でreallocを使用しているときにvoidへのポインタを使用できますか?
多くの感謝
解決
もちろん、realloc()
がNULL
を返すケースから保護する必要があります。これはメモリ割り当てであり、C(<=>)が主に使用されますが、C ++プログラマは生の<=>呼び出しを使用するのは少し低レベル/気だと思うと、メモリ割り当ては常に失敗する可能性があります。
ポインターを戻り値で直接上書きするとエラーになります。元のポインターがドロップされ、再割り当てが失敗した場合にメモリリークが発生するためです。
他のヒント
Malloc()およびrealloc()はC関数です。実際、realloc()は、渡す引数に応じてmalloc()およびfree()を実行します。
- nullポインターを渡すと、reallocはmallocの機能を実行します。
- ゼロサイズを渡すと、reallocはfreeと同じ動作をします。
こちらから引用。詳細な説明があります。
Cライブラリは、メモリブロックを所定の位置に拡張することを不可能にするため、C ++もそれをサポートしません。
C関数に固執したい場合は、realloc()を呼び出すときに最初のメモリ割り当てのポインタを保持する必要があります。次に、それがNULLであるかどうかを確認し、そうでない場合は、最新のコードで行ったように割り当てます。
ただし、C ++の場合、Cのmalloc()に基づいたstdソリューションである独自のmallocatorを作成するのが最善のソリューションかもしれません。 this またはこれ。
推奨されるアプローチを使用する<!>#8211; reallocが正常に戻るまで、前のバッファーへのポインターを保持します。 realloc()が正常に戻ると、前のブロックが解放され、そのブロックへのすべてのポインターがぶら下がります<!>#8211;それらを調整します。
reallocとmallocは、ポインタの種類を気にしません-void *とany *を使用できます。
他の人が言っているように、提案どおりにreallocを適切に使用してください。
しかし、<!> quot; C ++ way <!> quot;これを行うには、実際にstd :: vector <!> lt; <!> gt;を使用します。自分で配列を管理するのではなく。そうすれば、C ++標準ライブラリが再割り当ての低レベルの詳細を処理します(おそらくrealloc()を使用して)。
realloc()が失敗してNULLを返す場合、元のメモリは変更されません。
したがって、次のように使用する必要があります。
my_Struct* strPtr =(my_struct*)malloc(sizeof(my_Struct));
/* an later */
my_Struct* tmp = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);
if (tmp != NULL)
{
strPtr = tmp;
}
else
{
/* realloc Failed. Need to do something */
}
mallocとreallocを使用しているのはなぜですか?ほとんどの場合、C ++にはもっと良い方法があります。
これを使用して可変長配列を作成している場合、ほぼ確実にstd :: vector <!> lt; <!> gt;または他のコンテナテンプレートの1つを使用するほうが確実です。
代わりにCを使用している場合、おそらくC ++対応のコンパイラーを使用している場合、正しい方法は2番目の方法で、割り当てに失敗してもメモリブロック全体が失われることはありません。
2番目の質問に対する答えは、Cを使用しているかC ++を使用しているかによっても異なります。 Cでは、void *は汎用データポインター型であり、自由に変換できます。 C ++では、void *を明示的に変換する必要があります。実際にCを記述している場合は、malloc()およびフレンドを使用する必要があります。これらはvoid *で動作します。本当にC ++を書いている場合は、キャストする必要があります。どちらの場合も、realloc()は構造体へのポインターではなく、voidへのポインターで機能します。