2013-02-10 146 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运算符。然而,这个假设似乎对我所尝试过的所有事情都适用。