std::realloc
ヘッダ <cstdlib> で定義
|
||
void* realloc( void* ptr, std::size_t new_size ); |
||
指定されたメモリ領域を再確保します。 メモリ領域は以前に std::malloc()、 std::calloc() または std::realloc()
によって確保されていなければならず、まだ std::free() によって解放されていてはなりません。 そうでなければ、結果は未定義です。
再確保は以下のいずれかによって行われます。
ptr
の指す既存の領域を拡大または縮小します。 領域の内容は新しいサイズと古いサイズの小さい方まで変更されずに残されます。 領域が拡大される場合、配列の新しい部分の内容は未定義です。new_size
バイトの新しいメモリブロックを確保し、新しいサイズと古いサイズの小さい方と同じサイズのメモリ領域をコピーし、古いブロックを解放します。十分なメモリがない場合、古いブロックは解放されず、ヌルポインタが返されます。
ptr
がヌルポインタの場合、動作は std::malloc(new_size
) の呼び出しと同じです。
new_size
がゼロの場合、動作は処理系定義です。 ヌルポインタが返されるかもしれませんし (その場合、古いメモリブロックは解放されるかもしれませんし、されないかもしれません)、記憶域にアクセスするためには使用できない何らかの非ヌルなポインタが返されるかもしれません。
以下の関数はスレッドセーフであることが要求されます。
記憶域の特定の単位を確保または解放するこれらの関数の呼び出しは単一の全順序で発生し、そのような解放の呼び出しそれぞれはこの順序における次の確保 (もしあれば) に対して先行発生します。 |
(C++11以上) |
目次 |
[編集] 引数
ptr | - | 再確保するメモリ領域を指すポインタ |
new_size | - | 配列の新しいサイズ |
[編集] 戻り値
成功した場合は、新たに確保されたメモリの先頭を指すポインタを返します。 メモリリークを回避するためには、返されたポインタは std::free() で解放しなければなりません。 元のポインタ ptr
は無効化され、それに対するあらゆるアクセスは未定義動作になります (再確保がその場で行われた場合でも)。
失敗した場合は、ヌルポインタを返します。 元のポインタ ptr
は有効なまま残され、 std::free() で解放する必要があるかもしれません。
[編集] ノート
再確保は (拡大されるか縮小されるかにかかわらず) バイト単位のコピーを行う可能性があるため、 TriviallyCopyable な型のオブジェクトのみが realloc
の呼び出し後のメモリブロックの保存される部分で安全にアクセスできます。
非標準のライブラリには、以下のものを持たない型を表す型特性「BitwiseMovable」または「Relocatable」を定義しているものもあります。
- 外部参照 (別の要素を指す参照を保持するリストやツリーのノードなど)
- 内部参照 (別のメンバのアドレスを保持するかもしれないメンバポインタなど)
そのような型のオブジェクトは、コピーコンストラクタがトリビアルでなくても、記憶域の再確保後もアクセスすることができます。
[編集] 例
#include <cstdlib> #include <new> #include <cassert> class MallocDynamicBuffer { char* p; public: explicit MallocDynamicBuffer(std::size_t initial = 0) : p(nullptr) { resize(initial); } ~MallocDynamicBuffer() { std::free(p); } void resize(std::size_t newSize) { if(newSize == 0) { // this check is not strictly needed, std::free(p); // but zero-size realloc is deprecated in C p = nullptr; } else { if(void* mem = std::realloc(p, newSize)) p = static_cast<char*>(mem); else throw std::bad_alloc(); } } char& operator[](size_t n) { return p[n]; } char operator[](size_t n) const { return p[n]; } }; int main() { MallocDynamicBuffer buf1(1024); buf1[5] = 'f'; buf1.resize(10); // shrink assert(buf1[5] == 'f'); buf1.resize(1024); // grow assert(buf1[5] == 'f'); }
[編集] 関連項目
realloc の C言語リファレンス
|