我做错了什么? 在Mac(2GB RAM)上使用Eclipse时,我遇到了以下问题:
每当我尝试创建一个超过8384896字节的数组时,就会出现分段错误。将执行以下程序:
#include <stdio.h>
main()
{
double x[1048112];
printf("sizeof(x) = %li", sizeof(x));
}
并且输出将是(如预期的那样):
sizeof(x)= 8384896
但是增加x中的元素数量或在main()中创建其他变量会导致无法执行的程序和段错误。看起来我正在达到一些内存限制,我不明白为什么会发生这种情况。 如果有人能向我解释这个问题,或者为我的问题提供某种解决方案,我将非常感激。
答案 0 :(得分:14)
由于堆栈变量过大,这是stack overflow。
如果你真的需要分配大的东西,你可以使用malloc
在堆上这样做:
double *x = malloc(1048112 * sizeof(double));
请注意,通过此更改,sizeof(x)
不再返回数组的大小,它将返回double *
的大小。如果你需要知道你的阵列有多大,你需要自己跟踪它。
而且,为了完整起见,当您完成数据后,您需要调用free
,否则您将会遇到内存泄漏:
free(x);
答案 1 :(得分:7)
OS X上的进程受限制,默认为8MB堆栈(尝试从命令行运行ulimit -s
)。
一种选择是尝试使用ulimit -s 65536
之类的东西来增加堆栈大小。这应该会影响从当前shell会话运行的所有新进程。
更好的选择是在堆上分配数组:
double *x = (double*)malloc(9999999)
当你完成数组时,不要忘记使用以下方法解除分配:free(x)
编辑:尝试使用此reference获取有关如何使用链接器增加OS X上的最大堆栈大小的信息。同样,首选选项只是在堆上分配大型数组。更轻松,更便携。
答案 2 :(得分:3)
该问题的其他解决方案包括使用静态数组:
static double x[1234567];
在函数中,或在函数外使用全局变量。如果全局数组被声明为static,则它将在编译它的文件之外不可见。
无论哪种方式,每次调用例程时都不会更新阵列,因此每次调用它时都不会获得“新的开始”但是与以前相同的旧数据。
答案 3 :(得分:2)
是的,你正在达到内存限制......具体来说,你是Stack Overflow
。那你该怎么办 ?在堆上分配内存......如下:
double *x=malloc(1048112*sizeof(double));
答案 4 :(得分:2)
基于malloc的解决方案是正确的,但是这个解决方案可以省去自己跟踪内存的麻烦:
#include <stdio.h>
static double x[1048112];
main()
{
printf("sizeof(x) = %li", sizeof(x));
}
在函数体外部声明为静态的变量不会从堆栈中分配,并且它们的可见性仅限于它们所定义的文件。
答案 5 :(得分:0)
您可以通过链接器设置增加堆栈上允许的空间量,或者最好使用动态内存。
答案 6 :(得分:0)
作为旁注:根据我的经验,在某些情况下,这种性质的问题(“为什么我的巨大的自动阵列导致崩溃”)根植于初学者对数组对象的物理性质的误解。我不止一次遇到过那些坚信数组在物理上由一个“指针”组成的人,这些指针指向实际元素的附加内存块。他们还认为自动数组只占用少量的堆栈内存(对于所谓的“指针”),而大元素块则分配在别处,而不是堆栈中。这可能是人们(即使那些完全了解堆栈空间“有限”的人)看到定义大型自动数组没有问题的可能原因之一。
答案 7 :(得分:0)
只是让你知道windows中的这个限制是1 mb
此代码工作
void myfunction() { static char yes[1100000]//allocated in the heap }
此代码不起作用
void myfunction() { char yes[1100000]//allocated in the stack }