数组类型与使用malloc分配的数组之间的区别 [英] Difference between array type and array allocated with malloc

查看:262
本文介绍了数组类型与使用malloc分配的数组之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我正在用一个C代码帮助我的一个朋友,但我发现了一些奇怪的行为,无法解释他为什么会发生这种情况.我们有一个TSV文件,其中包含一个整数列表,每行一个整数.第一行是列表中的行数.

Today I was helping a friend of mine with some C code, and I've found some strange behavior that I couldn't explain him why it was happening. We had TSV file with a list of integers, with an int each line. The first line was the number of lines the list had.

我们还有一个带有非常简单的"readfile"的c文件.第一行被读取为n,即行数,然后进行了以下初始化:

We also had a c file with a very simple "readfile". The first line was read to n, the number of lines, then there was an initialization of:

int list[n]

最后是带有fscanf的n的for循环.

and finally a for loop of n with a fscanf.

对于小n(直到〜100.000),一切都很好.但是,我们发现,当n大(10 ^ 6)时,将发生段错误.

For small n's (till ~100.000), everything was fine. However, we've found that when n was big (10^6), a segfault would occur.

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

Finally, we changed the list initialization to

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

一切都很好,即使n很大.

and everything when well, even with very large n.

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

Can someone explain why this occurred? what was causing the segfault with int list[n], that was stopped when we start using list = malloc(n*sizeof(int))?

推荐答案

这里有几个不同的地方在玩.

There are several different pieces at play here.

第一个是将数组声明为

int array[n];

int* array = malloc(n * sizeof(int));

在第一个版本中,您声明一个具有自动存储持续时间的对象.这意味着该数组仅在调用它的函数存在的情况下存在.在第二个版本中,您将获得具有动态存储持续时间的内存,这意味着该内存将一直存在,直到用free显式释放为止.

In the first version, you are declaring an object with automatic storage duration. This means that the array lives only as long as the function that calls it exists. In the second version, you are getting memory with dynamic storage duration, which means that it will exist until it is explicitly deallocated with free.

第二个版本在此处起作用的原因是通常如何编译C的实现细节.通常,C内存分为几个区域,包括堆栈(用于函数调用和局部变量)和堆(用于malloc ed对象).堆栈的大小通常比堆小得多.通常大约是8MB.结果,如果您尝试使用

The reason that the second version works here is an implementation detail of how C is usually compiled. Typically, C memory is split into several regions, including the stack (for function calls and local variables) and the heap (for malloced objects). The stack typically has a much smaller size than the heap; usually it's something like 8MB. As a result, if you try to allocate a huge array with

int array[n];

然后,您可能会超出堆栈的存储空间,从而导致段错误.另一方面,堆通常具有很大的大小(例如,与系统上的可用空间一样大),因此malloc处理大对象不会导致内存不足错误.

Then you might exceed the stack's storage space, causing the segfault. On the other hand, the heap usually has a huge size (say, as much space as is free on the system), and so mallocing a large object won't cause an out-of-memory error.

通常,请注意C中的可变长度数组.它们很容易超出堆栈大小.除非您知道大小很小或者您确实只想在短时间内使用数组,否则最好使用malloc.

In general, be careful with variable-length arrays in C. They can easily exceed stack size. Prefer malloc unless you know the size is small or that you really only do want the array for a short period of time.

希望这会有所帮助!

这篇关于数组类型与使用malloc分配的数组之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆