简体   繁体   English

内存段堆栈和堆

[英]Memory segments stack and heap

i've looked over so many topics and i still could not find out why this happens:我查看了很多主题,但仍然无法找出发生这种情况的原因:

struct B
{
    int _arr[5];
};
struct A
{
    struct B * _pb;
};
int main() {
    int i;

    struct B b;
    struct A *pa = (struct A*)malloc(sizeof (struct A));
    for (i=0;i<5;++i)
    {
        b._arr[i] = i;
    }
    pa->_pb=&b;
    Struct A a = *pb;
}

How come pa found on stack and *pa is found on heap!为什么 pa 在堆栈上找到而 *pa 在堆上找到! both are local variables and should be only valid through scope so it should be on stack.两者都是局部变量,应该只在范围内有效,所以它应该在堆栈上。 also why is ‪a._pb->_arr[2] on stack should not be on heap?还有为什么 a._pb->_arr[2] 在堆栈上不应该在堆上? can anyone clarify for me when it should be on stack and when on heap谁能为我澄清什么时候应该在堆栈上,什么时候应该在堆上

The variable pa is on the stack.变量pa在堆栈上。 The memory it points to is on the heap.指向的内存在堆上。

Somewhat graphically a pointer variable can be describes like this:有点图形化的指针变量可以这样描述:

+----+     +--------------------------------+
| pa | --> | allocated memory for structure |
+----+     +--------------------------------+

The two locations illustrated above ( pa and the memory it points to) can be in different "segments", or they can be in the same.上面说明的两个位置( pa和它指向的内存)可以在不同的“段”中,也可以在同一段中。

And a._pb->_arr[2] is on the stack because a._pb is pointing to b which is on the stack.并且a._pb->_arr[2]位于堆栈上,因为a._pb指向堆栈上的b

Lastly a note about the "stack".最后是关于“堆栈”的说明。 While it's common to store local variables on the stack, the C specification doesn't say anything about it.虽然将局部变量存储在堆栈上是很常见的,但 C 规范并未对此进行任何说明。 Local variables are really automatic variables , and the C specification only specifies the semantics of those not where they should be stored.局部变量是真正的自动变量,C 规范只指定了那些不应该存储它们的地方的语义。

First off, the C standard says nothing about stacks and heaps.首先,C 标准没有提及栈和堆。 Those are implementation details of a given compiler.这些是给定编译器的实现细节。 That being said, most compilers for desktop applications use both of these.话虽如此,大多数桌面应用程序的编译器都使用这两种方法。

You are correct that pa is local to the main function and therefore resides on the stack.您是正确的, pamain函数的本地函数,因此驻留在堆栈上。 *pa however is not a local variable. *pa然而不是局部变量。 It is an expression which evaluates to an instance of struct A .它是一个计算结果为struct A实例的表达式。

In this case, the malloc function returns a pointer to a block of memory big enough for a struct A and the value of that pointer is stored in pa .在这种情况下, malloc函数返回一个指针,指向一个足够大的内存块用于struct A并且该指针的值存储在pa

Generally speaking, anything returned by malloc , realloc , or calloc lives in the heap, while variables declared local to a function (even pointer variables which may point to the heap) reside on the stack.一般而言, mallocrealloccalloc返回的任何内容都位于堆中,而声明为函数局部的变量(甚至可能指向堆的指针变量)则位于堆栈中。

Short answer: *pa (what pa points to) is found on the heap because that's where you allocated the memory using malloc().简短回答:*pa(pa 指向的内容)在堆上找到,因为那是您使用 malloc() 分配内存的地方。 The variable pa, the pointer itself, is allocated on the stack because it's a local variable.指针本身变量 pa 被分配在堆栈上,因为它是一个局部变量。

Long answer: Make sure you note the difference between a pointer and what the pointer refers to.长答案:确保您注意指针和指针所指内容之间的区别。

A declaration like this:像这样的声明:

int a[5]内部 [5]

Tells the compiler to reserve space for a 5-element array, while a declaration like this:告诉编译器为 5 元素数组保留空间,同时声明如下:

int *a;整数 *a;

Tells the compiler to reserve space for a pointer.告诉编译器为指针保留空间。 If you want the pointer to refer to an array then you need to allocate the memory, usually on the heap using malloc() and then release it when you're done using free().如果你想让指针指向一个数组,那么你需要分配内存,通常在堆上使用 malloc(),然后在使用 free() 完成后释放它。

And just to confuse things, in the C language, the array operator, [], is equivalent to the pointer arithmetic *() so that these two statements are wholly equivalent, regardless of whether a was declared as a pointer or an array:更让人困惑的是,在 C 语言中,数组运算符 [] 等价于指针算术 *() ,因此这两个语句是完全等价的,无论 a 被声明为指针还是数组:

a[2] = 5; [2] = 5;

*(a + 2) = 5; *(a + 2) = 5;

Digression: Which leads to some amusing possibilities.题外话:这会导致一些有趣的可能性。 The above two statements are also equivalent to this one:上面两个语句也等价于这个:

2[a] = 5; 2[a] = 5;

Because addition is commutative in C:因为加法在 C 中是可交换的:

2[a] = 5; 2[a] = 5;

*(2 + a) = 5; *(2 + a) = 5;

*(a + 2) = 5; *(a + 2) = 5;

a[2] = 5; [2] = 5;

But this absolutely does not work in C++ for reasons that are too far afield for this digression.但这在 C++ 中绝对不起作用,原因是离题太远了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM