C语言 堆栈和堆中的内存分配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6770596/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:11:11  来源:igfitidea点击:

memory allocation in Stack and Heap

cmemory-managementheap-memorydynamic-allocationstack-memory

提问by Samir Baid

This may seem like a very basic question, but its been in my head so:

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

When we allocate a local variable, it goes into stack. Similarly dynamic allocation cause the variable to go on heap. Now, my question is, is this variable actually lie on stack or heap or we will just a reference in the stack and Heap.

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

For example,

例如,

Suppose I declare a variable int i. Now this iis allocated on the stack. So, when I print the address of i, this will be one of the location on stack? Same question for heap as well.

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

回答by Chris Eberle

I'm not entirely sure what you're asking, but I'll try my best to answer.

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

The following declares a variable ion the stack:

下面i在堆栈上声明一个变量:

int i;

When I ask for an address using &iI get the actual location on the stack.

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

When I allocate something dynamically using malloc, there are actually TWOpieces of data being stored. The dynamic memory is allocated on the heap, and the pointer itself is allocated on the stack. So in this code:

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

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

This is allocating space on the heap for an integer. It's also allocating space on the stack for a pointer (j). The variable j's value is set to the address returned by malloc.

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

回答by Darren Engwirda

Hopefully the following is helpful:

希望以下内容有帮助:

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

In the case of stack variables, the variable itself (the actual data) is stored on the stack.

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

In the case of heap allocated memory, the underlying data is always stored on the heap. A pointer to this memory/data maybe stored locally on the stack.

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

Hope this helps.

希望这可以帮助。

回答by Suroot

The pointer variable itself would reside on the stack. The memory that the pointer points to would reside on the heap.

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

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

iwould reside on the stack, the actual memory that i points to *iwould be on the heap.

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

回答by Prateek

I agree with Chris. Just another way to explain that. Consider the following code:

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

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

Even after using free(j) which should deallocate the memory from the heap, the pointer still exists and we need to explicitly make it NULL. This definitely suggests that there is also a stack counterpart of the pointer otherwise it should have been inexistent after the free command. This stack variable is the one pointing to the address on the heap where the memory was dynamically allocated using malloc.

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

回答by solidak

Mr. Eberle's answer is 100% correct, but since Google shows this as the first answer when searching for malloc heap or stack, I have to add that malloc()allocates data on the heap 'most' of the time. If the allocated data was larger than MMAP_THRESHOLDwhich is usually 128kb on 32-bit systems, malloc()will notuse the heap and instead allocates the data in an Anonymous Memory Segmentlocated usually below the stack, growing in the direction of low memory.

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

This is the same region that dynamically loaded libraries are located (libc.so, etc.). Here's the relevant passage from man malloc:

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

Normally, malloc() allocates memory from the heap, and adjusts the size of the heap as required, using sbrk(2). When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(2). MMAP_THRESHOLD is 128 kB by default, but is adjustable using mallopt(3). Prior to Linux 4.7 allocations performed using mmap(2) were unaffected by the RLIMIT_DATA resource limit; since Linux 4.7, this limit is also enforced for allocations performed using mmap(2).

通常,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) 执行的分配。

As a practical example, feel free to check the following post. It basically allocates 300kb with malloc()and then runs pmap <PID>to show the relevant memory segment.

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

回答by Anh Pham

stack or heap are not separate memory, they are memory segments that a running program is allocated by the system, just different ways of organizing data in memory.

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

So when you get &i, it is a memory address, simple as that.

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