2010-12-19 35 views
4

我們希望在低延遲系統上工作,堆分配在應用程序中成本較高。但是在某種程度上允許在堆上創建對象。這就是爲什麼我們想要指示對象是否被創建在堆上?如何知道對象創建是堆還是不堆?

下面的方法是找出在堆內存上創建的對象的正確方法。

將有泛型類,其中new和delete操作符被重載,以保持堆中分配指針....

#include <iostream> 
#include <set> 

using namespace std; 

class MemStat    //base class 
{ 
    typedef set<MemStat*> POINTERS; 
    static POINTERS m_ptrlist; 
public: 
    void* operator new (size_t size) 
    { 
     MemStat* ptr = ::new MemStat; 
     m_ptrlist.insert(ptr); 
     return ptr; 
    } 
    void operator delete(void* dptr) 
    { 
     MemStat* ptr = static_cast<MemStat*>(dptr); 
     m_ptrlist.erase(ptr); 
     ::delete ptr; 
    } 
    // void* operator new[] (size_t sz); 
    // void operator delete[] (void*); 

    bool is_on_heap() { m_ptrlist.find(this) != m_ptrlist.end(); } 

protected:    // ctor & dtor are protected for restrictions 
    MemStat() { } 
    virtual ~MemStat() { } 
    MemStat(const MemStat&) { } 
    const MemStat& operator=(const MemStat&) { return *this; } 
}; 
MemStat::POINTERS MemStat::m_ptrlist; 

爲此我們需要檢查堆創建將來源於終端用戶類MemStat類在實例化基類對象時使用新的&刪除操作符調用。

class MyClass : public MemStat //end user class 
{ 
}; 

int main() 
{ 
    MyClass* myptr = new MyClass; 
    MyClass obj; 

    cout << myptr->is_on_heap() << endl; //results into yes 
    cout << obj.is_on_heap() << endl;  //reults into no 

    delete myptr; 
} 

回答

6

請注意,您的方案悲慘只要一個MyClass對象失敗是一個子對象可能會或可能不會通過動態分配的另一個對象的(繼承或包含)。 (並且我知道用於防止動態分配的技巧也會失敗。)

因此,您所做的只是進一步減慢了堆分配而沒有獲得太多。除少數非常罕見的情況外,如果某個對象被分配了,則該類別的內容爲'用戶決定。
如果他們認爲他們需要動態分配一個,你不同意誰?

+0

任何數量的分配器調試方案也會導致指針不完全匹配。因此'set'是不合適的。但是,應該可以通過存儲每個分配的大小並在搜索中使用該信息來查明「this」是否屬於任何分配的區域。根據代碼的可移植性,可以使用底層分配器的堆棧行爲API,而不是冗餘地存儲塊信息。 – 2010-12-19 16:29:08

相關問題