2010-08-26 33 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

相關問題