堆栈和堆中的内存分配

这似乎是一个非常基本的问题,但它一直在我脑海中:

当我们分配一个局部变量时,它会进入堆栈。 类似地,动态分配会导致变量进入堆。 现在,我的问题是,这个变量实际上是在堆栈还是堆上,或者我们只是堆栈和堆中的引用。

例如,

假设我声明了一个变量int i 。 现在这个i被分配在堆栈上。 那么,当我打印i的地址时,这将是堆栈中的一个位置? 堆的问题也一样。

我不完全确定你在问什么,但我会尽力回答。

以下声明堆栈上的变量i

 int i; 

当我使用&i要求地址时&i我得到堆栈上的实际位置。

当我使用malloc动态分配内容时,实际上存储了两个数据。 动态内存在堆上分配,指针本身在堆栈上分配。 所以在这段代码中:

 int* j = malloc(sizeof(int)); 

这是在堆上为整数分配空间。 它还在堆栈上为指针( j )分配空间。 变量j的值设置为malloc返回的地址。

希望以下内容对您有所帮助:

 void foo() { // an integer stored on the stack int a_stack_integer; // a pointer to integer data, the pointer itself is stored on the stack int *a_stack_pointer; // make a_stack_pointer "point" to integer data that's allocated on the heap a_stack_pointer = (int*)malloc(10 * sizeof(int)); } 

在堆栈变量的情况下,变量本身(实际数据)存储在堆栈中。

在堆分配内存的情况下,底层数据始终存储在堆上。 指向该存储器/数据的指针可以本地存储在堆栈上。

希望这可以帮助。

指针变量本身将驻留在堆栈上。 指针指向的内存将驻留在堆上。

 int *i = malloc(sizeof(int)); 

i将驻留在堆栈上,我指向*i的实际内存将在堆上。

我同意克里斯的观点。 只是另一种解释的方式。 请考虑以下代码:

 int* j = malloc(sizeof(int)); free(j); 

即使使用了free(j),它应该从堆中释放内存,指针仍然存在,我们需要显式地使它为NULL。 这肯定表明指针的堆栈对应物,否则它应该在free命令之后不存在。 此堆栈变量是指向堆上的地址的变量,其中使用malloc动态分配内存。

堆栈或堆不是单独的内存,它们是由系统分配运行程序的内存段,只是在内存中组织数据的不同方式。

所以,当你得到&i时,它是一个内存地址,就这么简单。

Eberle先生的答案100%正确,但由于Google在搜索malloc heap or stack时将其显示为第一个答案,我必须补充说malloc()在“大多数”时间内在堆上分配数据。 如果分配的数据大于MMAP_THRESHOLD (在32位系统上通常为128kb malloc() ,则malloc()使用堆,而是在通常位于堆栈下方的匿名内存段中分配数据,从而在低内存方向上增长。

这是动态加载库所在的区域( libc.so等)。 这是man malloc的相关段落:

通常,malloc()从堆中分配内存,并根据需要使用sbrk(2)调整堆的大小。 当分配大于MMAP_THRESHOLD字节的内存块时,glibc malloc()实现使用mmap(2)将内存分配为私有匿名映射。 MMAP_THRESHOLD默认为128 kB,但可以使用mallopt(3)进行调整。 在Linux 4.7之前,使用mmap(2)执行的分配不受RLIMIT_DATA资源限制的影响; 从Linux 4.7开始,对于使用mmap(2)执行的分配,也强制执行此限制。

作为一个实际的例子,请随时查看以下post 。 它基本上用malloc()分配300kb,然后运行pmap 来显示相关的内存段。