堆栈和堆中的内存分配

时间:2011-07-21 02:09:09

标签: c memory-management heap-memory dynamic-allocation stack-memory

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

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

例如,

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

6 个答案:

答案 0 :(得分:42)

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

以下声明堆栈中的变量i

int i;

当我使用&i询问地址时,我得到了堆栈中的实际位置。

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

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

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

答案 1 :(得分:10)

希望以下内容有所帮助:

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));
}

对于堆栈变量,变量本身(实际数据)存储在堆栈中。

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

希望这有帮助。

答案 2 :(得分:5)

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

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

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

答案 3 :(得分:2)

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

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

先生。 Eberle的答案是100%正确的,但是由于Google在搜索malloc heap or stack时将其显示为第一个答案,因此我必须补充一点,malloc()大部分时间都是在堆上分配数据。如果分配的数据大于MMAP_THRESHOLD(在32位系统上通常为128kb),则malloc()使用堆,而是以 Anonymous内存段通常位于堆栈下方,向低内存方向扩展。

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

  

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

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