例如,分配器如何创建和销毁和数组
int* someInt = someAllocator(3);
没有分配器的地方就是这样
int* someInt = new int[3];
分配器负责创建每个元素并确保将调用构造函数.
如何在不使用新的情况下编写分配器的内部结构?有人可以提供功能的例子吗?
我不想只使用std :: vector,因为我试图了解一个分配器如何创建一个数组.
最佳答案 一般内存分配的问题是一个令人惊讶的棘手问题.有些人认为它已经解决了,有些人无法解决;)如果你对内部感兴趣,首先看看
Doug Lea’s malloc.
专门的存储器分配器通常要简单得多 – 为简单性和性能而交换通用性(例如,通过使大小固定).但要小心,使用通用内存分配通常比实际程序中的特殊分配器更好.
一旦通过内存分配器的“魔力”分配了一块内存,就可以使用placement 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.