1

今天遇到一个奇怪的错误,还是没看懂:

long long N = 2000;
long long N2 = N*N;
long long *s = malloc(sizeof(long long)*N2); // create array
// populate it
for (long long k = 1; k <= 55; k++) {

不会产生任何错误,但是

long long N = 2000;
long long N2 = N*N;
long long s[4000000]; // create array
// populate it
for (long long k = 1; k <= 55; k++) {

在将 1 分配给 k之前for(根据调试器),在行上给我一个 code=2 EXC_BAD_ACCESS ,就好像没有空间可以分配另一个 8 字节变量一样。此代码位于方法的开头;没有分配或分配其他变量。我猜我根本无法将 4000000 个元素的 long long 数组分配给堆栈,但不知何故我可以将它分配给动态堆。有人可以解释发生了什么,限制是什么等?这是运行 Mountain Lion、2GB RAM 的 Mac 上的 Objective-C。long long 是 8 字节宽,所以数组应该只有 32MB;我不明白为什么这应该是一个问题。

谢谢!

(顺便说一句,如果细节看起来很熟悉,那是因为这是我解决 Project Euler问题 149的开始。我已经避免在这里提到解决方案的任何细节,因为我已经解决了这个问题。)

4

2 回答 2

3

您的第一个示例从堆中分配内存,位于“数据段”中,第二个示例在堆栈上分配内存,位于“堆栈段”中。这些中的每一个都有不同的大小限制。

根据Technical Q&A QA1419,默认堆栈段大小限制为 8 MiB。您可以通过ulimit -a在终端中运行来仔细检查:

:; ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited

如您所见,堆栈大小限制为 8192 KiB = 8 MiB。

我上面链接的技术问答描述了一些增加堆栈大小限制的方法。在不以 root 身份运行的情况下,您可以将其增加到的最大值为 64 MiB。

如果您创建线程,则每个线程都有自己的堆栈。根据问答,如果您使用NSThreadAPI,则可以将线程的堆栈大小设置为 1 GiB。

于 2012-09-13T21:20:14.583 回答
2

自动本地分配在堆栈上;根据此技术说明,OSX 进程的主线程的默认堆栈大小为 8MB,而附加线程的堆栈大小则更少。您可以尝试setrlimit注释中给出的链接器选项或解决方案,但 C 的传统是将堆用于任何大型分配。

于 2012-09-13T21:19:35.337 回答