4

たとえば、アロケータはどのように作成、破棄、配列しますか

int* someInt = someAllocator(3);

アロケータがなければ、

int* someInt = new int[3];

アロケーターが各要素を作成し、コンストラクターが呼び出されるようにする責任があります。

newを使用せずにアロケータの内部をどのように記述しますか?誰かが関数の例を提供できますか?

アロケータが配列を作成する方法を学習しようとしているので、std::vectorだけを使用したくありません。

4

2 に答える 2

2

一般的なメモリ割り当ての問題は、驚くほど難しい問題です。解決したと考える人もいれば、解決できないと考える人もいます;)内部に興味がある場合は、まずDougLeaのmallocを見てください。

特殊なメモリアロケータは、通常、はるかに単純です。単純さとパフォーマンスのために、一般性(サイズを固定するなど)と引き換えになります。ただし、現実的なプログラムでは、通常、一般的なメモリ割り当てを使用する方が、特別なアロケータの寄せ集めよりも優れていることに注意してください。

メモリアロケータの「魔法」を介してメモリのブロックが割り当てられると、配置newを使用してコンテナの自由に初期化できます。

- - 編集 - -

newの配置は、「通常の」プログラミングには役立ちません。メモリ割り当てをオブジェクトの構築から分離するために独自のコンテナを実装する場合にのみ必要になります。そうは言っても、配置を使用するための少し工夫された例を次に示します。

#include <new> // For placement new.
#include <cassert>
#include <iostream>

class A {
public:
    A(int x) : X(x) {
        std::cout << "A" << std::endl;
    }
    ~A() {
        std::cout << "~A" << std::endl;
    }
    int X;
};

int main() {

    // Allocate a "dummy" block of memory large enough for A.
    // Here, we simply use stack, but this could be returned from some allocator.
    char memory_block[sizeof(A)];

    // Construct A in that memory using placement new.
    A* a = new(memory_block) A(33);

    // Yup, it really is constructed!
    assert(a->X == 33);

    // Destroy the object, wihout freeing the underlying memory
    // (which would be disaster in this case, since it is on stack).
    a->~A();

    return 0;

}

これは印刷します:

A
~A

---編集2---

OK、これがアレイに対してどのように行うかです:

int main() {

    // Number of objects in the array.
    const size_t count = 3;

    // Block of memory big enough to fit 'count' objects.
    char memory_block[sizeof(A) * count];

    // To make pointer arithmetic slightly easier.
    A* arr = reinterpret_cast<A*>(memory_block);

    // Construct all 3 elements, each with different parameter.
    // We could have just as easily skipped some elements (e.g. if we
    // allocated more memory than is needed to fit the actual objects).
    for (int i = 0; i < count; ++i)
        new(arr + i) A(i * 10);

    // Yup, all of them are constructed!
    for (int i = 0; i < count; ++i) {       
        assert(arr[i].X == i * 10);
    }

    // Destroy them all, without freeing the memory.
    for (int i = 0; i < count; ++i)
        arr[i].~A();

    return 0;

}

ところで、デフォルトのコンストラクターがある場合は、このようなすべての要素で呼び出すことAができます...

new(arr) A[count];

...しかし、これはあなたが本当に扱いたくないワームの缶を開くでしょう。

于 2012-04-19T18:28:22.230 に答える
0

私はここで私の2番目の例でそれについて書きました:

新しい配置を使用する可能性があるときに配列を作成する方法

違いは、t_allocator::t_array_recordがクライアントではなくアロケータによって管理されることです。

于 2012-04-19T18:55:33.537 に答える