如何找到一个变量在栈或堆分配?(How to find if a variable is alloc

2019-07-04 13:59发布

在这次采访中偶然发现问题的地方,

在C语言中,给定一个变量x ,你怎么找出是否该变量的空间堆栈或堆在分配呢?

(有没有办法找到它编程,而不是不必通过符号表等?而如果空间在堆栈中分配或堆具有任何实际意义并发现?)

Answer 1:

不,不是一般。

你知道的gcc -fsplit-stack

它是由执行决定是否分配一个连续的叠层或其中,块被交错与存储器堆块的叠层。 好运搞清楚的块是否被分配给堆或当后者是分裂堆栈。

注:反正这是相当无用的信息...



Answer 2:

如果您在存储上比堆更大的地址栈架构的工作,你可以用堆的底部比较变量地址。 使用pthread的线程API,这种比较是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <inttypes.h>

int is_stack(void *ptr)
{
  pthread_t self = pthread_self();
  pthread_attr_t attr;
  void *stack;
  size_t stacksize;
  pthread_getattr_np(self, &attr);
  pthread_attr_getstack(&attr, &stack, &stacksize);
  return ((uintptr_t) ptr >= (uintptr_t) stack
          && (uintptr_t) ptr < (uintptr_t) stack + stacksize);
}

考试:

int main()
{
  int x;
  int *p1 = malloc(sizeof(int));
  int *p2 = &x;

  printf("%d %d\n", is_stack(p1), is_stack(p2));
  return 0;
}

...打印0 1 ,符合市场预期。

上面的代码将不会从其他线程堆栈检测存储。 要做到这一点,该代码将需要跟踪所有创建的线程。



Answer 3:

这是不以任何标准,但保证

在大多数平台上的栈从最高地址下可用,如果地址的最显著字节为平台的可用内存空间的上半部分堆从下往上增长,并且尚未分配的内存千兆字节,这是一个非常不错的选择,它的堆栈。

#include <iostream>
#include <stdlib.h>
int main()
{
int x = 0;
int* y = new int;

unsigned int a1 = (int) &x;
unsigned int a2 = (int) y;

std::cout<<std::hex<<a1<<"  "<<a2<<std::endl;
}

使输出ffbff474 21600我打字这个机器。



Answer 4:

这可能是一个有趣的问题。 变量具有自动或静态存储持续时间[*]。 你可以相当肯定地说,自动化分配“在堆栈上”,至少假设他们没有优化到寄存器中。 这并不是说会有“堆栈”标准的要求,但标准的C实现必须保持调用栈和准自动变量与调用堆栈的水平。 所以,无论其实际作用,你几乎可以称之为“堆栈”的细节。

具有静态存储持续时间的变量通常栖息一个或多个数据段。 从OS的POV,数据段可能从堆在程序启动之前分配的,但是从程序的POV他们没有关系了“免费商店”。

您可以通过检查其源定义告诉变量的存储时间-如果它在功能范围那么它的自动标记,除非static 。 如果它不是在功能范围那么它有静态的时间,无论它是否被标记为static (因为static关键字意味着不同的东西在那里)。

有没有可移植的方法来告诉其地址变量的存储时间,但具体的实现可能提供的方式来做到这一点,或工具,你可以用较大或较小的可靠性使用,以此来猜测。

对象也可以动态存储的持续时间(通常是什么“在堆中分配”是指),但这样的对象不是变量 ,所以这将是的伎俩,如果有一个。

[*]或者线程局部的C11和C ++ 11。



Answer 5:

我不认为它有解决方案。 该代码可以通过调整堆(堆)地址范围VAR的地址,但它不会是一个具体的方式。 至多,该代码可以在一些特定的平台上运行。



Answer 6:

不,这不是能够确定的存储位置,编译器会与isstack来支持它()是便携式的。



文章来源: How to find if a variable is allocated in stack or heap?
标签: c++ c stack heap