我注意到在使用一些大型数组(比如1000×1000)时,如果我在main()中声明了数组,那么我的程序会耗尽内存但是如果我在main之外声明数组,这似乎永远不会发生( )即使是较大的阵列。有人能解释一下这个区别是什么吗?
答案 0 :(得分:8)
当一个变量在一个函数内声明时(在你的情况下,main
),它被分配在堆栈上,如果它太大(例如,一个大数组),你会遇到{{3} }。
在所有函数之外定义的变量是静态分配的。它的生命周期一直持续到程序终止。
答案 1 :(得分:3)
这是与实施有关的问题。理论上定义一个内存消耗变量应该可以在与全局范围相同的函数中实现。
但实际上,全局范围中的变量将在目标机器代码的数据段中声明,并且有更多可用空间要分配。但是,在函数中通常会使用堆栈概念,但存在一些局限性。
答案 2 :(得分:2)
在大多数系统中,函数中声明的内存将进入堆栈,该内存很小并且可能会溢出。但是,在main()
之外声明的内存不会。堆栈的大小(和存在)是依赖于实现的 - 虽然我不知道任何常用的C ++系统,其中堆栈不存在。
从技术上讲,在函数内声明的内存具有automatic
存储持续时间,这意味着它在封闭代码块的开头分配,并且在代码块完成后无效。
在main之外声明的内存具有static
存储持续时间,这意味着它在程序启动时分配,并且在程序的生命周期内有效。
有关存储持续时间的更多信息,请参阅this link。
如果要在函数内声明大量内存,可以使用分配函数malloc
或new
。 This link清楚地解释了堆栈和堆之间的区别(虽然它是关于C而不是C ++,它仍然适用于C ++)。
答案 3 :(得分:1)
如果它是函数的本地函数(main
只是另一个函数),它将继续堆栈。 1000x1000x8 = 800万字节。这可能比堆栈大小更大。不同的编译器可能有不同的大小,但我认为默认值是1MB。
全局变量(它们具有静态存储)不在堆栈上分配,也不在堆上分配,而是在整个程序持续时间内大小保持不变的数据段上分配。
请注意,进程只有两个内存区域,堆栈和堆。它还有一个代码/文本段,一个用于程序中初始化静态变量的数据段,另一个称为bss段的数据段用于未初始化的静态变量。有关详情,请参阅Anatomy of a Program in Memory。
答案 4 :(得分:0)
你必须决定巨大的内存块是应该来自堆(决定是否动态分配数组)还是来自堆栈(在某个函数中有一个局部变量,在不在范围内时将被释放),在main puts之外全局地址空间中的数据在所有函数之间共享,在main之前分配,并在main完成后(在程序退出时)取消分配。
答案 5 :(得分:0)
当程序执行时,它将创建一个进程,该进程将占用内存中的固定内存大小。该过程包含四个部分,数据部分,代码部分,堆和堆栈。在这四个部分中,数据和代码部分的大小是固定的,而堆栈(存储局部变量,静态数据)和堆(存储动态内存分配数据)的大小在执行期间会有所不同。现在,如果您在全局区域中的主要均值之外声明变量,则它将存储在具有固定大小的过程的数据部分中。因此在main外部创建非常大的数组会在数据段中引起问题。如果将其存储在main中,则可以通过堆栈来管理其大小。
答案 6 :(得分:-3)
static int num[1000][1000];
那样声明它