【问题标题】:Implementing simple allocator实现简单的分配器
【发布时间】:2016-01-25 11:25:29
【问题描述】:

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

class Allocator 管理类向量的内存:

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);
};

类Allocator成员实现:

/*
    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 
} 

如何在函数malloc() 中检查可能的错误分配 allocate()1,当前方法是否正确?

编辑:

函数destroy()的实现是否正确2,能给我一个正确实现的例子吗?

在函数 deallocate() 中还有一个额外的参数 n,我不知道如何使用。


1.我知道我正在使用已弃用的std::auto_ptr,只是按照书的建议错误地试图在分配错误的情况下摆脱指针。

2。我读过the documentation for function destroy(),但考虑到分配的内存是一个连续的块,即free()d,通过传递malloc()返回的指针,唯一合理的对象销毁是分配一个默认值。

【问题讨论】:

  • 书籍推荐? auto_ptr 调用 delete 而不是 free。如果这本书真的这么说,那就认为整本书都是可疑的。如此严重的错误暴露了严重缺乏理解。
  • 没关系:auto_ptr 从未调用过free。也就是说,我根本不明白auto_ptr 在那里做什么。它似乎是货物狂热。
  • @MSalters 我已编辑以描述我使用 auto_ptr 的意图。本书版本 (2009) 仅暗示 C++11 之前的 &lt;memory&gt; 成员,即`auto_ptr`。

标签: c++ memory-management malloc free allocator


【解决方案1】:

std::bad_alloc 不是魔法生成的。 malloc 因返回 nullptr 而失败,并且没有任何东西可以将其转换为异常。你调用malloc,所以你必须手动检查返回值。

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

【讨论】:

  • 此分配器用于构建在数组之上的向量,即分配器动态更改数组的大小。我很难理解在数组元素上调用析构函数/构造函数是什么意思?您能否给我一个有关两个函数中的一个的实现示例。
  • @simplicisveritatis:作为数组的一部分并没有什么特别之处,这是基本的new(p) T / p-&gt;~T() 东西。
  • 我想我明白了你的意思:数组将保存一个动态分配对象的地址,该地址由new(p) T 创建并由p-&gt;~T() 销毁,对吧?
  • 默认构造时我知道new T,否则我知道new T(param)。你能澄清一下语法吗:new(p) T?
  • @simplicisveritatis: T 是您引入的模板参数,即要创建的对象类型。 new(p) T 在地址 p 的已分配但未使用的内存中创建一个默认创建的 T 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
  • 2012-02-15
  • 2014-07-02
相关资源
最近更新 更多