【问题标题】:C arrays on stack堆栈上的 C 数组
【发布时间】:2018-06-06 22:27:15
【问题描述】:

在 c(和 c++)中,可以通过以下方式创建整数数组:

int a[const];

其中 const 是编译时常量,或者

int *a = (int *) malloc(...);

根据我的理解,第一个在栈上分配内存,第二个在堆上。现在,据我所知,堆栈上的内存是有序的,以便程序可以根据需要将其从顶部弹出。这意味着数组中的元素不一定按顺序存储,这听起来很奇怪。

这里到底发生了什么?

编辑:

感谢大家的回复。通过您的回答和一些后续谷歌搜索,我找到了我困惑的根源。我假设程序只会真正使用堆栈的顶部变量,并将它们一一打开/关闭。

【问题讨论】:

  • 为什么不按顺序存储元素?否则它们将如何存储?
  • @Anton Quelle 不清楚您为什么做出以下简历:“这意味着数组中的元素不一定按顺序存储”
  • 一旦将a 传递给函数,就无法知道指针的来源是什么,因此机制必须 相同。所以它是一样的。
  • @TonyTannous 但数组保证是连续的。
  • 数组的元素总是按顺序存储的(而且是连续的!)。阵列生命周期的管理是完全不同的事情。此外,“堆”和“堆栈”在一段时间内(20 年或更长时间)一直是不准确的描述。

标签: c arrays stack


【解决方案1】:

虽然抽象 C 语言没有说明如何分配本地对象(即没有明确引用“堆栈”语言规范),但本地对象的存储持续时间与堆栈的 LIFO 属性非常一致:本地对象在他们的创作顺序相反。 最后创建的对象首先被销毁,反之亦然。

此原则统一适用于所有本地对象。数组也不例外。每个数组只是一个适当大小的连续内存字节块(顺便说一句,对于任何类型的对象都是如此)。数组没有什么特别之处。没有理由不按顺序存储数组元素。

每个数组对象都是在堆栈顶部完整创建的。并且当数组对象达到其存储持续时间的末尾时,就像您说的那样,它只是“从顶部弹出”。任何可能驻留在堆栈中的任何内容都应该在那时已经弹出。

【讨论】:

  • 我投了赞成票,因为这是迄今为止解决 OP 似乎存在的一些困惑的唯一答案。他们的问题表明,他们认为数组的各个元素可能会按照它们首先被赋值的顺序被推入堆栈,而这个答案表明数组对象是完整创建的。我认为对此进行扩展可能有助于澄清 OP 的工作原理。
  • 加一个表示数组在内存中继续。
【解决方案2】:

你可能误会了什么。

实际上,栈永远是顺序存储的。然而,堆栈的大小将比堆更受限制。虽然确实可以从堆栈中“弹出”东西,但这实际上不适用于声明本地数组的函数。

另一方面,堆可以增长。当内存不足时,malloc 实现将调用sbrk() 来请求额外的内存。这意味着,总体而言,堆不必是连续的,尽管当您调用 mallocrealloc 时,您可以确信内存至少与您请求的一样大,并且地址将是连续的(至少,从你的角度来看)。

【讨论】:

  • 你能引用一个明确说明堆栈必须是连续的参考吗?
  • @TonyTannous 你能引用一个C 堆栈的引用吗?
  • @TonyTannous 不,但是在 40 年的 C 编程中,我从未见过一个平台,从 C 程序的角度来看,如果平台使用堆栈,堆栈是不连续的;作为惯例,这似乎是一个相当安全的选择。
  • 另外一个提到弹出堆栈不会发生在函数内
【解决方案3】:

编程中有3种主要的内存类型:静态内存、堆和堆栈。

静态内存用于分配所有“静态”变量,即在全局范围内声明的变量或在函数中声明为静态的变量。这意味着静态变量的数量和它们的大小在编译时是已知的,编译器只是为它们保留内存。

堆是一个动态的内存池,你可以在需要的时候借用内存并将内存归还给它。因此,当您借用内存时,即“malloc”它,您可以随意使用它,直到您归还(免费)它,以便它可以被程序的不同部分重用。

栈是一个特殊的内存区域,用于为函数分配局部变量。当您调用具有非静态局部变量的函数时,它将为内存中的这些变量分配足够的空间(加上函数需要的额外空间)。当你从函数返回时,内存会自动返回给系统,以便在另一个函数调用中重用。

在您的情况下,第一个声明可以是静态变量,也可以是局部函数变量。根据这一点,它可以分配在这些池之一中。第二种情况是从堆中借用内存。

通常每个变量都占用内存中的连续空间。它是哪种类型的内存都没有关系。数组就是这样一个占用内存区域的变量。数据放入内存的顺序本身取决于架构。编译器的任务是为您提供变量的标准视图,即 array[0] 应该包含 array[0] 的数据,并且指针运算应该以标准方式工作。

因此,实际上,数组的所有元素都是按顺序存储的。如果没有,它不会改变编程中的任何内容。虽然我还没有看到他们不会这样的情况。

【讨论】:

    猜你喜欢
    • 2013-02-11
    • 2019-07-24
    • 2020-03-20
    • 2010-11-26
    • 1970-01-01
    • 2020-06-12
    • 2012-11-18
    • 2014-12-14
    • 2020-04-09
    相关资源
    最近更新 更多