Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
堆栈上的C数组 在C和C++中,可以用以下方式创建整数数组: int a[const];_C_Arrays_Stack - Fatal编程技术网

堆栈上的C数组 在C和C++中,可以用以下方式创建整数数组: int a[const];

堆栈上的C数组 在C和C++中,可以用以下方式创建整数数组: int a[const];,c,arrays,stack,C,Arrays,Stack,其中const是编译时常量,或 int *a = (int *) malloc(...); 根据我的理解,第一个在堆栈上分配内存,第二个在堆上分配内存。现在,据我所知,堆栈上的内存是按顺序排列的,这样程序就可以根据需要将其从顶部弹出。这意味着数组中的元素不一定按顺序存储,这听起来很奇怪 这里到底发生了什么 编辑: 谢谢你们的回复。通过你的回答和一些后续的谷歌搜索,我找到了困惑的根源。我假设程序只会真正使用堆栈的顶层变量,然后逐个打开/关闭它们 你可能误解了什么 实际上,堆栈始终是顺序存储。然而

其中const是编译时常量,或

int *a = (int *) malloc(...);
根据我的理解,第一个在堆栈上分配内存,第二个在堆上分配内存。现在,据我所知,堆栈上的内存是按顺序排列的,这样程序就可以根据需要将其从顶部弹出。这意味着数组中的元素不一定按顺序存储,这听起来很奇怪

这里到底发生了什么

编辑:


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

你可能误解了什么

实际上,堆栈始终是顺序存储。然而,堆栈的大小将比堆限制得多。虽然确实会从堆栈中弹出内容,但这实际上不适用于声明本地数组的函数


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

编程中有3种主内存类型:静态内存,堆积如山

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

Heap是一个动态内存池,您可以在需要时借用内存并将内存返回给它。所以,当你借用内存,即“malloc”它时,你可以随心所欲地使用它,直到你释放它,这样它就可以被程序的不同部分重用

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

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

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


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

而抽象C语言没有说明如何分配本地对象,即没有明确引用堆栈语言规范,本地对象的存储时间与堆栈的后进先出属性很好地一致:本地对象按与其创建相反的顺序销毁。最后创建的对象首先被销毁,反之亦然

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


每个数组对象都是在堆栈顶部完整创建的。当array对象到达其存储持续时间的末尾时,它会像您所说的那样从顶部弹出。任何可能位于堆栈中其上方的元素都应该在那一刻被弹出。

为什么元素不按顺序存储?否则它们将如何存储?@Anton Quelle不清楚您为什么要做以下恢复:这意味着数组中的元素不一定是按顺序存储的。一旦将a传递给函数,就无法知道指针的来源,因此机制必须相同。所以是一样的。@TonyTannous,但数组保证是连续的。数组的元素总是按顺序连续存储的!。阵列生存期的管理是一件完全不同的事情。堆和堆栈的描述也有一段时间不准确了2
0年或更长时间。你能引用一个明确表示堆栈必须是连续的引用吗?@TonyTannous你能引用一个C有堆栈的引用吗?@TonyTannous没有,但在40年的C编程中,我从未见过一个平台,从C程序的角度来看,如果平台使用堆栈,那么堆栈是不连续的;作为一个惯例,这似乎是一个相当安全的赌注。另外一个原因是提到在一个函数中不会出现弹出堆栈的情况。我对此投了赞成票,因为这是迄今为止唯一一个解决OP似乎存在的一些困惑的答案。他们的问题表明,他们认为数组中的各个元素可能会按照它们首先被赋值的顺序被推到堆栈上,这个答案表示数组对象是完整创建的。我认为在这一点上再扩展一点可能有助于为OP阐明事情是如何工作的。另外还有一个说明数组在内存中是连续的。