C++ 大尺寸阵列上的分段错误

C++ 大尺寸阵列上的分段错误,c++,arrays,segmentation-fault,C++,Arrays,Segmentation Fault,当在2Gb机器上运行时,下面的代码给出了一个分段错误,但在4GB机器上工作 int main() { int c[1000000]; cout << "done\n"; return 0; } 阵列的大小仅为4Mb。可以在C++中使用的数组的大小有限制吗? ,您可能只是在这里获得了堆栈溢出。数组太大,无法放入程序的堆栈地址空间 如果您在堆上分配数组,那么假设您的机器有足够的内存,您应该可以 整数*数组=新整数[1000000] 但请记住,这将要求您删除[]数组。一

当在2Gb机器上运行时,下面的代码给出了一个分段错误,但在4GB机器上工作

int main()
{
   int c[1000000];
   cout << "done\n";
   return 0;
}

阵列的大小仅为4Mb。可以在C++中使用的数组的大小有限制吗?

,您可能只是在这里获得了堆栈溢出。数组太大,无法放入程序的堆栈地址空间

如果您在堆上分配数组,那么假设您的机器有足够的内存,您应该可以

整数*数组=新整数[1000000]


但请记住,这将要求您删除[]数组。一个更好的解决方案是使用STD::vector并将其调整为1000000个元素。

在堆栈上分配C++数组。在这种情况下,尝试使用AlLoc分配相同大小的数组。您在堆栈上分配了一个大数组,超出了堆栈的处理能力,因此您得到了一个

不要在堆栈上本地分配,而是使用其他位置。这可以通过使对象成为全局对象或在全局堆上分配对象来实现。如果不使用来自任何其他编译单元的,则全局变量可以。为了确保这不会意外发生,请添加一个静态存储说明符,否则只需使用堆

这将在BSS段中分配,BSS段是堆的一部分:

static int c[1000000];
int main()
{
   cout << "done\n";
   return 0;
}
int main()
{
   int* c = new int[1000000];
   cout << "done\n";
   return 0;
}
这将在数据段中分配,数据段也是堆的一部分:

int c[1000000] = {};
int main()
{
   cout << "done\n";
   return 0;
}
这将在堆中的某个未指定位置进行分配:

static int c[1000000];
int main()
{
   cout << "done\n";
   return 0;
}
int main()
{
   int* c = new int[1000000];
   cout << "done\n";
   return 0;
}

因为您将数组存储在堆栈中。您应该将其存储在堆中。请参阅以了解堆和堆栈的概念。

此外,如果在大多数UNIX和Linux系统中运行,可以通过以下命令临时增加堆栈大小:

ulimit -s unlimited

但要小心,内存是一种有限的资源,巨大的能力带来了巨大的责任:

您的普通数组是在堆栈中分配的,而堆栈仅限于几个magabytes,因此您的程序会出现堆栈溢出和崩溃

最好是使用基于堆分配的数组,它可以增长到几乎整个内存的大小,而不是普通数组

在上面的示例中,您得到几乎相同的行为,就像您分配了普通数组int c[100][456][123];除了向量在堆上而不是堆栈上分配之外,您可以像在普通数组中一样以c[10][20][30]的形式访问元素。上面的这个例子也在堆上分配数组,这意味着数组大小可以达到整个内存大小,而不受堆栈大小的限制


要获取指向向量中第一个元素的指针,请使用&c[0]或c.data。

谢谢您的回答,但您能否解释一下为什么数组分配在堆栈上,为什么不分配在主程序内存中。给定的代码分配在堆栈上,因为它在编译时被指定为元素数恒定的数组。值仅与malloc、new等一起放在堆上。所有自动变量都在堆栈上分配。如果查看disassable,您将看到从堆栈指针中减去的局部变量的大小。当您调用malloc或calloc或任何内存函数时,这些函数会找到足够大的内存块来满足您的请求。@Charles为什么我们可以从堆而不是从堆栈分配更多内存?据我所知,堆栈和堆在内存中分配的地址空间中都朝相反的方向移动。@saurabhagarwal堆不移动。它甚至不是一个连续的内存区域。如果使用第三种模式(在堆上分配),不要忘记在某个阶段删除[]指针,否则会泄漏内存。分配器只返回一个符合您大小要求的可用内存块。或者查看智能指针。@meowsqueak当然,删除使用新指针分配的所有位置是一种很好的做法。但是,如果您确定只像在main中一样分配内存一次,则严格来说,这是不需要的-即使没有显式删除,也保证在main的出口处释放内存。'at'drhirsch您如何处理at字符?-是的,评论不错。由于OP对语言来说是新的,我只是想确保他们和其他看到您的好答案的人都知道第三个选项的含义(如果普遍使用)。这是解决方案,但我建议所有人在删除程序堆栈大小的默认限制时要非常谨慎。您不仅会经历严重的性能下降,而且系统可能会崩溃。例如,我试图在一台4GB内存的机器上使用快速排序对一个包含1600000个整数元素的数组进行排序,结果我的系统几乎被杀死。LOL@rbaleksandar我认为您的16MB程序几乎要杀死您的机器,因为您使用的是阵列的多个副本,每个函数调用可能只有一个?尝试更具内存意识的实现;我非常确定数组处理是正常的,因为我是通过引用而不是通过值传递的。泡泡运动也会发生同样的情况。见鬼,即使我的快速排序实现很糟糕
s bubblesort是您不可能错误实现的东西。哈哈,你可以试试基数排序,或者干脆用std::sort:没机会。这是一项实验任务D