2013-02-10 245 views
1

我試圖做一個機制,可以告訴哪裏的類的對象分配。 想到在類中創建標誌,但無法設置值,因爲在調用「新」運算符期間未啓動對象的生命週期。 在C++中可以判斷一個對象是堆棧還是堆(運行時)?堆棧或堆上的對象分配

+4

你需要什麼? – 2013-02-10 12:22:31

+1

不以任何便攜式方式。 – juanchopanza 2013-02-10 12:22:55

+0

那麼,您可以嗅探周圍的彙編指令,就像Apple在Objective-C運行時中所做的那樣。 – 2013-02-10 12:28:26

回答

1

我一直在做一些實驗,並且已經發現,這似乎爲工作能夠總是在運行時告訴對象是否在堆棧上分配。

的界面如下:

#ifndef HEAPAWARE_H 
#define HEAPAWARE_H 

#include <cintttypes> 

class HeapAware 
{ 
public: 
    HeapAware(); 
    void *operator new(std::size_t size); 
    void *operator new[](std::size_t size); 
    void operator delete(void *ptr, std::size_t); 
    void operator delete[](void *ptr, std::size_t); 
    bool is_on_heap() const { return on_heap; } 
    std::ptrdiff_t get_heap_array_index() const { return heap_array_index; } 
private: 
    const bool on_heap; 
    const std::ptrdiff_t heap_array_index; 
    static thread_local HeapAware * last_alloc; 
    static thread_local std::size_t allocated_size; 
}; 
#endif 

和實現是:

void *HeapAware::operator new(std::size_t size) 
{ 
    auto result = last_alloc = reinterpret_cast<HeapAware*>(malloc(size)); 
    allocated_size = 1; 
    return result; 
} 
void *HeapAware::operator new[](std::size_t size) 
{ 
    auto result = last_alloc = reinterpret_cast<HeapAware*>(malloc(size)); 
    allocated_size = size; 
    return result; 
} 
void HeapAware::operator delete(void *ptr, std::size_t) 
{ 
    free(ptr); 
} 
void HeapAware::operator delete[](void *ptr, std::size_t) 
{ 
    free(ptr); 
} 

HeapAware::HeapAware():on_heap(this>=last_alloc && this<last_alloc+allocated_size),heap_array_index(allocated_size>1?this-last_alloc:-1) 
{ 
} 

thread_local HeapAware * HeapAware::last_alloc = nullptr; 
thread_local std::size_t HeapAware::allocated_size = 0; 

這似乎總是正常工作。對於在堆上分配的數組,條目的索引也是可用的。對於在堆棧中分配的值或僅分配給單個項的值,get_heap_array_index()函數返回-1。

這段代碼的假設是在任何給定的線程上構造之前立即調用new運算符。然而,這個假設似乎對我所嘗試過的所有事情都適用。