c++ - 分配器如何创建和销毁数组?

标签 c++ design-patterns memory memory-management

例如,分配器如何创建和销毁数组

int* someInt = someAllocator(3);

没有分配器的地方

int* someInt = new int[3];

分配器负责创建每个元素并确保调用构造函数。

如何在不使用 new 的情况下编写分配器的内部结构?有人可以提供功能示例吗?

我不想只使用 std::vector,因为我正在尝试学习分配器如何创建数组。

最佳答案

一般内存分配问题是一个非常棘手的问题。有些人认为它已解决,有些人认为无法解决 ;) 如果您对内部结构感兴趣,请先查看 Doug Lea's malloc。 .

专用 内存分配器通常要简单得多 - 它们以通用性(例如,通过固定大小)换取简单性和性能。不过要小心,在实际程序中使用通用内存分配通常比特殊分配器的大杂烩更好。

一旦通过内存分配器的“魔法”分配了一 block 内存,容器就可以使用 placement new 对其进行初始化。 .

--- 编辑 ---

放置 new 对于“正常”编程没有用 - 只有在实现自己的容器以将内存分配与对象构造分开时才需要它。话虽这么说,这里有一个使用 placement 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 ---

好的,这是你如何为数组做的:

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];

...但这会打开一个 can of worms你真的不想处理。

关于c++ - 分配器如何创建和销毁数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10234178/

相关文章:

c++ - 创建一个 C++ 程序来处理电话线(固定电话)上的来电

c - 如何将链表的头节点地址存储在文件中并稍后检索

c++ - openmp中的并行for循环

design-patterns - 命令模式的uml图

c# - 这是单一职责原则的一个例子吗?

c# - 抽象类使用哪个具体类?设计问题?

c++ - cpp 中枚举的内存要求是多少?

javascript - 如何使用 1 个全局内存数组模拟 JavaScript 中带有参数和局部变量的调用堆栈?

c++ - 枚举从原始类型继承

c++ - 'cmake' 未被识别为内部或外部命令