名前空間
変種
操作

std::realloc

提供: cppreference.com
< cpp‎ | memory‎ | c
 
 
 
動的メモリ管理
未初期化記憶域
(C++17)
ガベージコレクションサポート
その他
(C++20)
(C++11)
(C++11)
C のライブラリ
realloc
低水準のメモリ管理
 
ヘッダ <cstdlib> で定義
void* realloc( void* ptr, std::size_t new_size );

指定されたメモリ領域を再確保します。 メモリ領域は以前に std::malloc()std::calloc() または std::realloc() によって確保されていなければならず、まだ std::free() によって解放されていてはなりません。 そうでなければ、結果は未定義です。

再確保は以下のいずれかによって行われます。

a) 可能であれば、 ptr の指す既存の領域を拡大または縮小します。 領域の内容は新しいサイズと古いサイズの小さい方まで変更されずに残されます。 領域が拡大される場合、配列の新しい部分の内容は未定義です。
b) サイズ 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');
}


[編集] 関連項目