我有
class Foo {
....
}
Run Code Online (Sandbox Code Playgroud)
有没有办法让Foo能够分开:
function blah() {
Foo foo; // on the stack
}
Run Code Online (Sandbox Code Playgroud)
和
function blah() {
Foo foo* = new Foo(); // on the heap
}
Run Code Online (Sandbox Code Playgroud)
我希望Foo能够做出不同的事情,这取决于它是在Stack上堆还是堆.
编辑:
Alof的人问我"为什么这样做?"
答案:
我现在正在使用重新计算的GC.但是,我希望能够运行标记和扫描.为此,我需要标记一组"根"指针 - 这些是堆栈上的指针.因此,对于每个类,我想知道它们是在堆栈中还是在堆中.
sth*_*sth 18
一种hacky方式:
struct Detect {
Detect() {
int i;
check(&i);
}
private:
void check(int *i) {
int j;
if ((i < &j) == ((void*)this < (void*)&j))
std::cout << "Stack" << std::endl;
else
std::cout << "Heap" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
如果对象是在堆栈上创建的,那么它必须位于外部函数堆栈变量的方向上.堆通常从另一侧生长,因此堆栈和堆将在中间的某处相遇.
(确定系统不会起作用)
pax*_*blo 10
你需要真正问我们真正的问题:-)你很明白为什么你认为这是必要的,但几乎肯定不是.事实上,这几乎总是一个坏主意.
为什么你认为你需要这样做?
我经常发现这是因为开发人员想要根据分配的位置删除或不删除对象,但这通常应留给代码的客户端而不是代码本身.
更新:
道歉,你可能已经找到了你要问的几个领域之一.理想情况下,您将覆盖所有内存分配和取消分配运算符,以跟踪从堆中创建和删除的内容.
但是,我不确定拦截类的新/删除是一件简单的事情,因为可能存在delete未调用的情况,并且由于标记/扫描依赖于引用计数,因此您需要能够拦截指针赋值为了它正常工作.
你有没有想过如何处理这个问题?
经典的例子:
myobject *x = new xclass();
x = 0;
Run Code Online (Sandbox Code Playgroud)
不会导致删除调用.
另外,您将如何检测到指向某个实例的指针在堆栈中的事实?拦截new和delete可以让你存储对象本身是堆栈还是基于堆,但是我不知道你如何分辨指针的分配位置,特别是代码如:
myobject *x1 = new xclass(); // yes, calls new.
myobject *x2 = x; // no, it doesn't.
Run Code Online (Sandbox Code Playgroud)
答案是否定的,没有标准/可移植的方式来做到这一点.涉及重载新操作员的黑客往往会有漏洞.依赖于检查指针地址的黑客是特定于操作系统和特定于堆的实现,并且可能随着操作系统的未来版本而改变.您可能对此感到满意,但我不会围绕此行为构建任何类型的系统.
我会开始寻找不同的方法来实现你的目标 - 或许你可以有一个完全不同的类型作为你的方案中的"根",或者要求用户(正确地)使用特殊的构造函数来注释堆栈分配的类型.
小智 8
如果将“this”的值与堆栈指针的当前值进行比较,则是可能的。如果这个 < sp 那么你已经在堆栈中分配了。
试试这个(在 x86-64 中使用 gcc):
#include <iostream>
class A
{
public:
A()
{
int x;
asm("movq %1, %%rax;"
"cmpq %%rsp, %%rax;"
"jbe Heap;"
"movl $1,%0;"
"jmp Done;"
"Heap:"
"movl $0,%0;"
"Done:"
: "=r" (x)
: "r" (this)
);
std::cout << ( x ? " Stack " : " Heap " ) << std::endl;
}
};
class B
{
private:
A a;
};
int main()
{
A a;
A *b = new A;
A c;
B x;
B *y = new B;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它应该输出:
Stack
Heap
Stack
Stack
Heap
Run Code Online (Sandbox Code Playgroud)