2015-07-21 128 views
0

使用C++,获取堆栈指针或在X64上获取msvC++中堆栈指针的最大值的最简单估计的最快方法是什么?使用C++,如何获取msvc中堆栈指针的值X64

我打算用它来写这个内联函数:

static __forceinline bool IsOnStack(const void *p) { 
    return UINT_PTR(p) < __ESP; 
} 

我可以用它作为一个宏

#define ISONSTACK(a) 

感谢,如果这是更好!

编辑

我需要知道,如果事情是在堆栈上的其他代码不会释放它。只需说出它是传统的智能指针实现方式,我就可以加快速度。我必须处理的是智能指针所指对象的地址。我正在做一个改变,所以一个智能指针可以引用堆栈中的一个项目,这将消除堆栈分配过多。 64位堆栈看起来是一个相对较低的虚拟地址。我们的分配器使用预定义的虚拟基地址(现在是16GB)。我可以假设任何低于堆叠的东西。这个方法可能会意外地假定任何分配malloc或:: new的东西都在堆栈中,这不会是世界的尽头,因为我们不应该使用这些东西。我想我会看看是否有更好的方法来获得堆栈所在的位置。只要我们没有得到虚假的消极影响,性能比精确性更重要。

编辑

我知道我们目前只分配智能指针来分配内存,因为我们只用2种方式来设置智能指针:

new(spFoo) CFoo(); // uses an overridden new to do this 

spFoo = spOtherFoo; 

我想添加:

CFoo Foo(); 
spFoo = &Foo; 

编辑 我应该补充一点,我们不使用std库(部分原因是代码太旧,部分原因是我们的应用程序是边缘案例,性能非常重要)。我不想让这个关于标准库的争论,我们都同意这很好。我没有这个应用程序。我们的代码仅在内部服务器上运行。我们的代码全部是64位。有时我们使用线程,但这很少见。可移植性不是问题。我们使用microsoft visual studio 2013,它是vC++ 2012.我们在server 2008上运行。我们将在某一天升级到server 2012,并在Visual Studio 2015出现时升级。

这开始与通常抱怨内联汇编不可用。然后,我很难找到有关在Windows上运行的vC++应用程序的常规内存布局(堆栈,堆的位置等)的文档。

+1

似乎解决方案的东西,你不应该需要......为什么你需要知道是否有东西在堆栈上? [换句话说,你可能会问一个XY问题] –

+0

在栈上声明一个变量并取其地址。但是@MatsPetersson说你可能不需要知道这一点。 –

+0

我也很好奇,为什么你甚至需要做这样的事情?另外,我不认为这会做你认为它会做的事。你能提供一个你的总体目标的例子吗?也许是它的一个xy问题,我宁愿在x中工作:) – ydobonebi

回答

0

好的,所以这会比“评论”的价值更长。

首先“知道你是否需要免费”,应该用std::shared_ptrstd::unique_ptr来解决,而不是“检查它是否在堆栈上”。关于什么:

void Function(int *p) 
{ 
    if (!isOnStack(p)) delete p; 
} 


std::vector<int> v; 

... fill stuff into v ... 
Function(&v[14]); 

中释放的std::vector中间几乎可以肯定是一个非常糟糕的事情 - 但我保证的地址不是在堆栈中。

static int x; 
Function(&x); 

那里没有更好 - 它也会造成不好的自由。关于“堆栈所在位置”完全基于运行时环境(OS和编译器等的组合)。这可能是一个很高的地址。它可能是“主”线程中的高地址,而次线程中是低地址 - 但是您并不真的希望这只能在“主”线程中工作,对吗?

线程堆栈的位置当然也完全依赖于提供线程(和堆栈分配)的操作系统和运行时库。

你可以做一些事情,如:

uintptr_t sp_base; 

bool isInStack(void *p) 
{ 
    int x; 
    uintptr_t sp_top = (uintptr_t)(&x); 
    // Assumes stack grows towards 0. 
    return (p > sp_top) && (p < sp_base); 
} 

int main() 
{ 
    int x; 
    sp_base = (uintptr_t)(&x); 
    ... 
} 

但它远没有保证每工作时间,甚至大部分的时间 - 这取决于实际的操作系统和编译器的选择,结果可能会有所不同相当疯狂。

+0

谢谢。我们只使用visual studio编译器,只能在windows上运行。我们的软件仅供内部使用。与内存管理相关的功能被隔离在几个类中,所以如果我们愿意的话,我们可以轻松移植。性能是最重要的,所以一切都是自定义的。我们不使用标准库。 64位编译代码似乎在内存中找到堆栈低位,紧跟在exe映像之后。堆在堆栈后立即返回地址。我的猜测是线程在堆上分配它们的堆栈,这是在相同的低内存位置。 – johnnycrash