名前空間
変種
操作

std::realloc

From cppreference.com
< cpp‎ | memory‎ | c
 
 
メモリ管理ライブラリ
(説明用*)
未初期化メモリのアルゴリズム
(C++17)
(C++17)
(C++17)
制約付き未初期化
メモリアルゴリズム
Cライブラリ
realloc

アロケータ
メモリリソース
ガベージコレクションのサポート
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
未初期化ストレージ
(C++20まで*)
(C++20まで*)
明示的な生存期間管理
 
ヘッダ <cstdlib> で定義
void* realloc( void* ptr, std::size_t new_size );

指定されたメモリ領域を再割り当てします(宛先領域にオブジェクトを暗黙的に作成します)。このメモリは、事前に std::mallocstd::calloc、または std::realloc によって割り当てられ、まだ std::free によって解放されていない必要があります。そうでない場合、結果は未定義です。

再割り当ては、以下のいずれかの方法で行われます。

a) 可能であれば、ptr が指す既存の領域を拡張または縮小します。領域の内容は、新しいサイズと古いサイズの小さい方までは変更されません。領域が拡張された場合、配列の新しい部分の内容は未定義です。
b) サイズ new_size バイトの新しいメモリブロックを割り当て、新しいサイズと古いサイズの小さい方と等しいサイズのメモリ領域をコピーし、古いブロックを解放します。

メモリが不足している場合、古いメモリブロックは解放されず、ヌルポインタが返されます。

もし ptr がヌルポインタの場合、その動作は std::malloc(new_size) を呼び出した場合と同じです。

もし new_size がゼロの場合、その動作は実装定義です。ヌルポインタが返される場合(その場合、古いメモリブロックは解放される場合とされない場合があります)や、ストレージにアクセスできない非ヌルポインタが返される場合があります。このような使用は非推奨です(C DR 400経由)。(C++20以降)

以下の関数はスレッドセーフである必要がある

これらの関数に対する、特定のストレージ単位を割り当てるまたは解放する呼び出しは、単一の総順序で発生し、そのような各解放呼び出しは、この順序での次の割り当て(もしあれば)よりhappens-beforeである。

(C++11以降)

目次

[編集] パラメータ

ptr - 再割り当てするメモリ領域へのポインタ
new_size - 配列の新しいサイズ

[編集] 返り値

成功した場合、新しく割り当てられたメモリの先頭へのポインタを返します。メモリリークを回避するために、返されたポインタは std::free または std::realloc で解放する必要があります。元のポインタ ptr は無効になり、それへのアクセスはすべて未定義の動作となります(インプレース再割り当ての場合でも)。

失敗した場合、ヌルポインタを返します。元のポインタ ptr は有効なままであり、std::free で解放する必要がある場合があります。

[編集] ノート

再割り当ては(領域を拡張または縮小するかどうかにかかわらず)バイト単位のコピーを伴う可能性があるため、これらのオブジェクトが TriviallyCopyable 型であることが必要です(ただし、十分条件ではありません)。

そのような型("BitwiseMovable" または "Relocatable" と呼ばれることもあります)のオブジェクトは、コピーコンストラクタが自明でない場合でも、ストレージが再割り当てされた後にアクセスできます。

  • 外部参照(例:別の要素への参照を保持するリストまたはツリーのノード)を持たず、
  • 内部参照(例:別のメンバのアドレスを保持する可能性のあるメンバポインタ)を持たない

オブジェクトは、ストレージが再割り当てされた後でも、コピーコンストラクタが自明でない場合でもアクセスできます。

[編集]

#include <cassert>
#include <cstdlib>
#include <new>
 
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');
}

[編集] 関連項目

C のドキュメントrealloc について)
English 日本語 中文(简体) 中文(繁體)