您始终可以创建与 STL 一起使用的分配器。如果它适用于 STL,它应该适用于 boost,因为您可以将 boost 分配器传递给 STL 容器。
考虑到上述情况,可以在指定的内存地址分配并且具有您指定的大小限制的分配器可以编写如下:
#include <iostream>
#include <vector>
template<typename T>
class CAllocator
{
private:
std::size_t size;
T* data = nullptr;
public:
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T value_type;
CAllocator() {}
CAllocator(pointer data_ptr, size_type max_size) noexcept : size(max_size), data(data_ptr) {};
template<typename U>
CAllocator(const CAllocator<U>& other) noexcept {};
CAllocator(const CAllocator &other) : size(other.size), data(other.data) {}
template<typename U>
struct rebind {typedef CAllocator<U> other;};
pointer allocate(size_type n, const void* hint = 0) {return &data[0];}
void deallocate(void* ptr, size_type n) {}
size_type max_size() const {return size;}
};
template <typename T, typename U>
inline bool operator == (const CAllocator<T>&, const CAllocator<U>&) {return true;}
template <typename T, typename U>
inline bool operator != (const CAllocator<T>& a, const CAllocator<U>& b) {return !(a == b);}
int main()
{
const int size = 1024 / 4;
int ptr[size];
std::vector<int, CAllocator<int>> vec(CAllocator<int>(&ptr[0], size));
int ptr2[size];
std::vector<int, CAllocator<int>> vec2(CAllocator<int>(&ptr2[0], size));
vec.push_back(10);
vec.push_back(20);
vec2.push_back(30);
vec2.push_back(40);
for (std::size_t i = 0; i < vec2.size(); ++i)
{
int* val = &ptr2[i];
std::cout<<*val<<"\n";
}
std::cout<<"\n\n";
vec2 = vec;
for (std::size_t i = 0; i < vec2.size(); ++i)
{
int* val = &ptr2[i];
std::cout<<*val<<"\n";
}
std::cout<<"\n\n";
vec2.clear();
vec2.push_back(100);
vec2.push_back(200);
for (std::size_t i = 0; i < vec2.size(); ++i)
{
int* val = &ptr2[i];
std::cout<<*val<<"\n";
}
}
这个分配器确保所有内存都分配在指定的地址。无论是在堆栈上还是在堆上,都可以自由分配不超过您指定的数量。
您可以创建自己的池或使用 astd::unique_ptr
作为单个容器的池。
编辑:对于字符串,您需要sizeof(_Rep_base)
. 请参阅:为什么 std::string 分配两次?
和http://ideone.com/QWtxWg
它被定义为:
struct _Rep_base
{
std::size_t _M_length;
std::size_t _M_capacity;
_Atomic_word _M_refcount;
};
所以例子变成了:
struct Repbase
{
std::size_t length;
std::size_t capacity;
std::int16_t refcount;
};
int main()
{
typedef std::basic_string<char, std::char_traits<char>, CAllocator<char>> CAString;
const int size = 1024;
char ptr[size] = {0};
CAString str(CAllocator<char>(&ptr[0], size));
str = "Hello";
std::cout<<&ptr[sizeof(Repbase)];
}