Skip to content

Latest commit

 

History

History
145 lines (102 loc) · 4.1 KB

057-cpp17-lib-misc-memory.md

File metadata and controls

145 lines (102 loc) · 4.1 KB

メモリー管理アルゴリズム

C++17ではヘッダーファイル<memory>にメモリー管理用のアルゴリズムが追加された。

addressof

template <class T> constexpr T* addressof(T& r) noexcept;

addressofはC++17以前からもある。addressof(r)はrのポインターを取得する。たとえ、rの型がoperaotr &をオーバーロードしていても正しいポインターを取得できる。

struct S
{
    S * operator &() const noexcept
    { return nullptr ; } 
} ;

int main()
{
    S s ;

    // nullptr
    S * p1 = & s ;
    // 妥当なポインター
    S * p2 = std::addressof(s) ;

}

uninitialized_default_construct

template <class ForwardIterator>
void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class Size>
ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);

[first, last)の範囲、もしくはfirstからn個の範囲の未初期化のメモリーをtypename iterator_traits::value_typeでデフォルト初期化する。2つめのアルゴリズムはfirstからn個をデフォルト初期化する。

int main()
{
    std::shared_ptr<void> raw_ptr
    (   ::operator new( sizeof(std::string) * 10 ),
        [](void * ptr){ ::operator delete(ptr) ; } ) ;
 
    std::string * ptr = static_cast<std::string *>( raw_ptr.get() ) ;

    std::uninitialized_default_construct_n( ptr, 10 ) ;
    std::destroy_n( ptr, 10 ) ;
}

uninitialized_value_construct

template <class ForwardIterator>
void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class Size>
ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);

使い方はuninitialized_default_constructと同じ。ただし、こちらはデフォルト初期化ではなく値初期化する。

uninitialized_copy

template <class InputIterator, class ForwardIterator>
ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);

template <class InputIterator, class Size, class ForwardIterator>
ForwardIterator
uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);

[first, last)の範囲、もしくはfirstからn個の範囲の値を、resultの指す未初期化のメモリーにコピー構築する。

int main()
{
    std::vector<std::string> input(10, "hello") ;

    std::shared_ptr<void> raw_ptr
    (   ::operator new( sizeof(std::string) * 10 ),
        [](void * ptr){ ::operator delete(ptr) ; } ) ;
 
    std::string * ptr = static_cast<std::string *>( raw_ptr.get() ) ;


    std::uninitialized_copy_n( std::begin(input), 10, ptr ) ;
    std::destroy_n( ptr, 10 ) ;
}

uninitialized_move

template <class InputIterator, class ForwardIterator>
ForwardIterator
uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);

template <class InputIterator, class Size, class ForwardIterator>
pair<InputIterator, ForwardIterator>
uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);

使い方はuninitialized_copyと同じ。ただしこちらはコピーではなくムーブする。

uninitialized_fill

template <class ForwardIterator, class T>
void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);

template <class ForwardIterator, class Size, class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);

[first, last)の範囲、もしくはfirstからn個の範囲の未初期化のメモリーを、コンストラクターに実引数xを与えて構築する。

destory

template <class T>
void destroy_at(T* location);

location->~T()を呼び出す

template <class ForwardIterator>
void destroy(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class Size>
ForwardIterator destroy_n(ForwardIterator first, Size n);

[first, last)の範囲、もしくはfirstからn個の範囲にdestroy_atを呼び出す。