我正在尝试建立一种可以分辨出类对象分配位置的机制。 考虑在类中创建一个标志,但是不可能设置一个值,因为在调用“new”运算符期间没有启动对象的生命周期。 在C ++中是否可以判断对象是在堆栈还是堆(运行时)?
答案 0 :(得分:1)
没有可移植的方法可以做到这一点,但是如果我们假设你有一些有限的系统类型,你可以尝试以下方法:
获取main中某个局部变量的地址(或其他“callstack中的低位”)。将其存储在全局变量中,然后调用char *stackbase;
然后在您正在检入的函数中获取局部变量的地址,让我们称之为char *stacktop;
现在,如果我们有char *obj = reinterpret_cast<char *>(object_in_test);
,那么:
if (obj > stacktop && obj < stackbase) on_stack = true;
else on_stack = false;
请注意,这有以下几个缺陷:
>
和<
。not on stack
。 我完全希望不得不删除这个答案,因为它会被语言律师贬低,尽管下面有免责声明。
答案 1 :(得分:1)
我一直在做一些实验,并且发现这似乎能够在运行时始终告诉对象是否已在堆栈上分配。
界面如下:
if ($depOption == "bitcoin" or "ethereum" or "lisk")
{
// Get information on altcoin values
$request = 'https://api.coinmarketcap.com/v1/ticker/';
$response = file_get_contents($request);
$data = json_decode($response, true);
$price = null;
foreach ($data as $item) {
if ($item["id"] == "$depOption") {
$VAL = $item["price_usd"];
break;
}
}
}
elseif ($depOption == "EUR")
{
// Get EUR exchange rate
$eurrequest = 'http://api.fixer.io/latest';
$eurresponse = file_get_contents($eurrequest);
$eurdata = json_decode($eurresponse, true);
$VAL = $eurdata['rates']['USD'];
}
elseif ($depOption == "USD")
{
$VAL = 1;
}
else
{
die("Something went wrong.");
}
实施是:
#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;
函数返回-1。
此代码的假设是在构造任何给定线程之前立即调用new运算符。然而,这个假设似乎适用于我所尝试的一切。