2010-08-26 101 views
1

我与C++中的第三方C API集,有讨论关注两种方式工作:自定义分配器的std :: vector <>与释放?

  1. 它等同的malloc():the_api_malloc(大小)(加上匹配the_api_free() )
  2. 其中存储器与the_api_malloc创建()返回到一个函数具有的,并the_api_free()的所有权它在内部:the_api_give_back(PTR)

我已创建自定义分配器wrapp ing the_api_malloc()和the_api_free()用于例如std :: vector。这很好。

我想要做的是有一个std :: vector类型的类,它利用我的自定义分配器,但也有一个release()方法,当调用时释放它的内存所有权,因此不会调用我的自定义分配器the_api_free()。

pointer release() /* pointer is of T* */ 

用法示例:

MyClass myClass(1024); // the_api_malloc()'s 1024 bytes 
// ... do something with myClass 
the_api_give_back(myClass.release()); 

我不知道拉这一关的最佳途径。我现在作为一个实验是相当讨厌的:

class MyClass : public std::vector<char, MyAllocator<char> > { 
public: 
    using typename std::vector<char, MyAllocator<char> >::pointer; 

    pointer release() { 
     // note: visual studio impl. 
     pointer p = this->_Myfirst; 
     this->_Myfirst = 0; 
     this->_Mylast = 0; 
     this->_Myend = 0; 
     return p; 
    } 
} 

有没有更好的方法?

UPDATE 1:以下是我根据以下建议尝试过的。这也应该有助于说明目前失败的期望行为&。

template <class T> 
class MyAllocator 
{ 
public: 
    // types omitted for clarity 

    MyAllocator() : m_released(false) { } 

    template <class U> 
    MyAllocator(MyAllocator<U> const& a) : m_released(a.m_released) { } 

    // other ctors, dtors, etc. omitted for clarity 

    // note: allocate() utilizes the_api_malloc() 

    void deallocate(pointer p, size_type num) 
    { 
    if(!m_released) { 
     the_api_free(p); 
    } 
    } 

    void release_ownership() { m_released = true; } 

    bool m_released; 
}; 

template <typename T> 
char* ReleaseOwernship(T& container) 
{ 
    container.get_allocator().release_ownership(); 
    return &container[0]; 
} 

// usage: 
{ // scope 
    std::vector<char, MyAllocator<char> > vec; 

    // ...do something to populate vec... 

    char* p = ReleaseOwnership(vec); 
    the_api_give_back(p); // this API takes ownership of p and will delete it itself 
} // end scope - note that MyAllocator::deallocate() gets called here -- m_release is still false 

更新2:尝试创建一个MyOwningAllocator和MyNonOwningAllocator然后从所属交换到非拥有在哪里“释放时间”,但不能得到交换()来工作,因为他们是不同的类型。

回答

1

而不是试图停止调用分配器的免费函数的载体,我会包括您的release作为您的分配器的成员,并让它设置一个标志。当标志被设置时,the_api_free将简单地返回(即,充当nop)。

+0

分配器没有状态,所以我不知道我怎么能在一个标志? – NuSkooler 2010-08-27 03:22:36

+0

@NuSkooler:更准确地说,标准库不是*必需*来支持具有状态的分配器。尽管如此,这是我第一次尝试。如果内存服务,C++ 0x要求他们支持有状态的分配器,所以我猜想有一个很好的机会它会工作。如果你觉得真的需要,我只会做别的事情。 – 2010-08-27 03:35:16

+0

我在自定义分配器中创建了一个release_ownership(),用于设置成员bool的值。在deallocate()中,bool被选中,如果为true,则不执行任何操作。然而,release_ownership()和deallocate()之间的地址总是不同,所以bool总是为false(它是默认的)。 – NuSkooler 2010-08-27 16:51:35

1

vector::swap将把分配块的所有权转移给另一个vector。但是,在析构函数中没有办法阻止向量调用vector::allocator_type::deallocate,并且没有可移植的方法来直接修改内部指针。

+0

swap()的性能损失很重吗?我做这一切的关键是我可以利用STL(例如,vector <>)和C++,但现在是时候,将数据传递给C API,而不使用the_api_malloc()和memcpy()。如果swap()是轻量级的,我想我可以有一个非释放兼容的分配器来交换我以前想要调用release()的任何地方? – NuSkooler 2010-08-27 03:25:13

+0

@NuSkooler:'swap'非常非常快。在十几个机器周期的顺序。我不会在这里尝试一个自定义分配器。用'vector'替换接受控制的指针(swap前为空),用'swap'替换'release',并且应该设置。 – Potatoswatter 2010-08-27 03:36:52

+0

@Patatoswatter:对不起,如果我在这里密集:你是否建议我从自定义分配器(使用the_api_malloc())到标准向量的swap()?这不会导致第二个向量试图在内存被删除时删除吗?如果我完全不使用自定义分配器,则不会使用the_api_malloc()分配内存,因此不会由the_api_give_back()释放内存。也许我在这里错过了简单的东西? – NuSkooler 2010-08-27 04:12:45

相关问题