Namespaces
Variants

std:: realloc

From cppreference.net
< cpp ‎ | memory ‎ | c
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
ヘッダーで定義 <cstdlib>
void * realloc ( void * ptr, std:: size_t new_size ) ;

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

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

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

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

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) // このチェックは厳密には不要ですが、
        {
            std::free(p); // C言語ではゼロサイズのreallocは非推奨です
            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); // 縮小
    assert(buf1[5] == 'f');
    buf1.resize(1024); // 拡大
    assert(buf1[5] == 'f');
}

関連項目

C documentation for realloc
日本語訳:
翻訳内容: - "C documentation" → "Cドキュメント" - "for" → "の" (文脈に合わせて自然な日本語表現に変換) - "realloc" はC++用語のため翻訳せず保持