C++ 实现简单分配器

C++ 实现简单分配器,c++,memory-management,malloc,free,allocator,C++,Memory Management,Malloc,Free,Allocator,作为向量实现的一部分,我必须使用函数malloc()和free()实现分配器,给定以下接口: 类分配器管理类向量的内存: template<class T> class Allocator { public: // function members T* allocate(int n); void deallocate(T* p, int n); void construct(T* p, const T& v); void destr

作为向量实现的一部分,我必须使用函数
malloc()
free()
实现分配器,给定以下接口:

分配器
管理类向量的内存:

template<class T>
class Allocator {
public:
    // function members
    T* allocate(int n);
    void deallocate(T* p, int n);

    void construct(T* p, const T& v);
    void destroy(T* p);
};
如何从函数
allocate()
中的
malloc()
检查可能的错误分配,当前方法正确吗

编辑: 函数
destroy()
correct2,的实现正确吗?你能给我一个正确实现的例子吗

在函数
deallocate()
中还有一个附加参数
n
,我不知道该如何使用它


一,。我知道我正在使用一个不推荐使用的
std::auto_ptr
,只是错误地按照书中的建议尝试在分配错误的情况下删除指针


二,。我已经读过了,但是考虑到分配的内存是一个连续的块,通过传递malloc()返回的指针,它是
free()
d,唯一合理的对象销毁是分配一个默认值。

std::bad\u alloc
不是神奇地生成的
malloc
返回
nullptr
失败,没有任何东西会将其转换为异常。调用
malloc
,因此必须手动检查返回值


destroy
是错误的,原因与
construct
是错误的一样:它们是一对函数,将原始内存转换为对象并返回。通常的方法是放置新的直接调用析构函数。您只是在那里调用赋值运算符,这根本不会影响对象的生存期。

std::bad_alloc
不是神奇地生成的
malloc
返回
nullptr
失败,没有任何东西会将其转换为异常。调用
malloc
,因此必须手动检查返回值


destroy
是错误的,原因与
construct
是错误的一样:它们是一对函数,将原始内存转换为对象并返回。通常的方法是放置新的直接调用析构函数。您只需在那里调用赋值运算符,这根本不会影响对象的生存期。

书籍推荐<代码>自动ptr调用
删除
免费
。如果书真的这么说,就认为整本书都可疑。如此严重的错误暴露出人们严重缺乏理解。这无关紧要:
auto\u ptr
从未调用过
free
。也就是说,我根本不明白
auto_ptr
在那里做什么。它似乎是cargo culty。@我编辑了一些代码来描述我使用
auto\u ptr
的意图。图书版本(2009)仅表示C++11之前的
成员,即“自动”图书推荐<代码>自动ptr调用
删除
免费
。如果书真的这么说,就认为整本书都可疑。如此严重的错误暴露出人们严重缺乏理解。这无关紧要:
auto\u ptr
从未调用过
free
。也就是说,我根本不明白
auto_ptr
在那里做什么。它似乎是cargo culty。@我编辑了一些代码来描述我使用
auto\u ptr
的意图。图书版(2009)仅表示C++11之前的
成员,即“auto_ptr”。此分配器用于构建在数组之上的向量,即分配器动态更改数组的大小。我很难理解对数组元素调用析构函数/构造函数意味着什么?你能给我一个关于这两个函数的实现例子吗?@simplicisveritatis:作为数组的一部分没有什么特别的,它是基本的
new(p)T
/
p->~T()
东西。我想我明白你的意思了:数组将保存一个动态分配对象的地址,它由
new(p)T
创建,并由
p->~T()
销毁,对吗?我知道默认构造时
new T
,否则
new T(param)
。您能否澄清语法:
new(p)T
?@simplicisveritatis:
T
是您引入的模板参数,即要创建的对象类型
new(p)T
在地址
p
的已分配但未使用的内存中创建默认创建的
T
对象。此分配器用于构建在数组之上的向量,即分配器动态更改数组的大小。我很难理解对数组元素调用析构函数/构造函数意味着什么?你能给我一个关于这两个函数的实现例子吗?@simplicisveritatis:作为数组的一部分没有什么特别的,它是基本的
new(p)T
/
p->~T()
东西。我想我明白你的意思了:数组将保存一个动态分配对象的地址,它由
new(p)T
创建,并由
p->~T()
销毁,对吗?我知道默认构造时
new T
,否则
new T(param)
。您能否澄清语法:
new(p)T
?@simplicisveritatis:
T
是您引入的模板参数,即要创建的对象类型
new(p)T
在地址
p
处已分配但未使用的内存中创建默认创建的
T
对象。
/*
    Function: allocate()
    Use: allocator_object.allocator(num_of_elements) 

    Implicit in vector_base constructor.
    It wraps malloc(); Throws bad_alloc
    if allocation unsuccessful.
*/
template <class T>
T* Allocator<T>::allocate(int n) {
    try {
        std::auto_ptr<T> mem_ptr = reinterpret_cast<T*>(malloc(n * sizeof(T)));
    } catch (std::bad_alloc& e) {
        std::cerr <<"bad_alloc caught: "<< e.what() <<'\n';
        throw;
    }
    return mem_ptr.release();
}

/*
    Function: deallocate()
    Use: allocator_object.deallocate(mem_ptr, redundant_par);

    Implicit in base_vector destructor.
    It returns memory to free store. 
    First argument is the pointer returned by malloc(). 
*/
template <class T>
void Allocator<T>::deallocate(T* mem_ptr, int n) {
    free(mem_ptr);
}

/*
    Function: construct()
    Use: allocator_object.construct(elem_ptr[i], value)

    Implicit in vector_base constructor
    and all modifying members of vector.
    It assigns the value passed as second
    argument to the element with address
    held by the pointer passed as a first 
    argument.
*/
template <class T>
void Allocator<T>::construct(T* p, const T& v = T()) {
    *p = v;
}

/*
    Function: destroy()
    Use: allocator_object.destroy(elem_ptr[i]); 

    Implicitly in vector members: reserve(), resize();
    It assigns type default value to the element
    with address held by the pointer passed as argument.
*/
template <class T>
void Allocator<T>::destroy(T* p) {
    *p = T(); // ? not sure if right 
}