猿问

数组类型和使用malloc分配的数组之间的区别

数组类型和使用malloc分配的数组之间的区别

今天我用一些C代码帮助了我的一个朋友,我发现了一些奇怪的行为,我无法解释他为什么会发生这种行为。我们有一个带有整数列表的TSV文件,每行都有一个int。第一行是列表的行数。

我们还有一个非常简单的“readfile”的ac文件。第一行读到n,行数,然后有一个初始化:

int list[n]

最后是一个带有fscanf的n循环。

对于小n(直到~100,000),一切都很好。但是,我们发现当n很大(10 ^ 6)时,会发生段错误。

最后,我们将列表初始化更改为

int *list = malloc(n*sizeof(int))

一切都很好,即使是非常大的n。

有人能解释为什么会这样吗?什么导致了segfault [n]的段错误,当我们开始使用list = malloc(n * sizeof(int))时停止了?


蛊毒传说
浏览 1561回答 3
3回答

偶然的你

这里有几个不同的作品。第一个是将数组声明为的区别int array[n];和int* array = malloc(n * sizeof(int));在第一个版本中,您声明一个具有自动存储持续时间的对象。这意味着只要存在调用它的函数,该数组就会存在。在第二个版本中,您将获得具有动态存储持续时间的内存,这意味着它将一直存在,直到它被显式释放free。第二个版本在这里工作的原因是如何编译C的实现细节。通常,C内存分为几个区域,包括堆栈(用于函数调用和局部变量)和堆(用于malloced对象)。堆栈的大小通常比堆小得多; 通常它是8MB的东西。因此,如果您尝试分配一个巨大的数组int array[n];然后,您可能会超出堆栈的存储空间,从而导致段错误。另一方面,堆通常具有巨大的大小(例如,系统上空闲的空间),因此malloc大型对象不会导致内存不足错误。通常,要注意C中的可变长度数组。它们很容易超过堆栈大小。malloc除非您知道尺寸很小或者您确实只想要在短时间内使用该阵列,否则请首选。希望这可以帮助!

慕虎7371278

int list[n]为堆栈n上的整数分配空间,这通常很小。使用堆栈上的内存比替代方法快得多,但是它非常小并且如果您执行诸如分配大型数组或过度递归之类的操作,则很容易溢出堆栈(即分配太多内存)。您不必手动释放以这种方式分配的内存,它是在阵列超出范围时由编译器完成的。malloc另一方面,在堆中分配空间,与堆栈相比通常非常大。您将不得不在堆上分配更大量的内存来耗尽它,但是在堆上分配内存比在堆栈上分配内存要快得多,并且必须free在完成使用后手动取消分配它。

呼唤远方

int list [n]将数据存储在堆栈中,而malloc将其存储在堆中。堆栈是有限的,并没有太多的空间,而堆更大。
随时随地看视频慕课网APP
我要回答