46

以下代码为我生成堆栈溢出错误

int main(int argc, char* argv[])
{
    int sieve[2000000];
    return 0;
}

我该如何解决这个问题?我正在使用 Turbo C++,但想将我的代码保留在 C 中

编辑:

感谢您的建议。上面的代码只是举例,我实际上在函数中声明了数组,而不是在 sub main 中。此外,我需要将数组初始化为零,所以当我搜索 malloc 时,我发现 calloc 非常适合我的目的。

Malloc/calloc 也比在堆栈上分配的优点是允许我使用变量声明大小。

4

8 回答 8

62

您的数组太大而无法放入堆栈,请考虑使用堆:

int *sieve = malloc(2000000 * sizeof(*sieve));

如果您真的想更改堆栈大小,请查看此文档。

提示: - 不要忘记在不再需要时释放动态分配的内存。

于 2009-02-21T02:16:08.833 回答
14

有3种方式:

  1. malloc()正如其他海报所建议的那样,在堆使用上分配数组。不要忘记free()它(尽管main()它并不重要 - 操作系统会在程序终止时为您清理内存)。
  2. 在单元级别声明数组 - 它将在数据段中分配并对所有人可见(添加static到声明将限制单元的可见性)。
  3. 将您的数组声明为static- 在这种情况下,它将在数据段中分配,但仅在main().
于 2009-02-21T08:42:47.233 回答
1

您最好将其分配在堆上,而不是堆栈上。就像是

int main(int argc, char* argv[])
{
    int * sieve;
    sieve = malloc(20000);
    return 0;
}
于 2009-02-21T02:17:02.653 回答
1

这大约是 7MB 的堆栈空间。在 Visual Studio 中,您将使用 /STACK:###,### 来反映您想要的大小。如果你真的想要一个巨大的堆栈(可能是一个很好的理由,使用 LISP 或其他东西 :),即使堆在强制你使用 VirtualAlloc 之前也仅限于 small'sh 分配),你可能还想将你的 PE 设置为构建/LARGEADDRESSAWARE(又是 Visual Studio 的链接器),但此配置是您的 PE 标头,以允许您编译的二进制文件寻址完整的 4GB 32 位地址空间(如果在 WOW64 中运行)。如果构建真正庞大的二进制文件,您通常还需要将 /bigobj 配置为附加的链接器参数。

如果您仍然需要更多空间,您可以通过使用类似于(再次 MSVC 的链接)/merge: 的东西来彻底违反约定,这将允许您将一个部分打包到另一个部分中,因此您可以将每个字节用于单个共享代码/数据部分。当然,您还需要在 def 文件或 #pgrama 中配置 SECTIONS 权限。

于 2009-02-21T03:04:06.457 回答
1

使用malloc。所有检查返回类型是否为空,如果它为空,那么您的系统根本没有足够的内存来容纳那么多值。

于 2009-02-22T06:59:56.130 回答
0

你的数组很大。

您的机器或操作系统可能没有或不想分配这么多内存。


如果您绝对需要一个巨大的数组,您可以尝试动态分配它(使用malloc(...)),但是您有内存泄漏的风险。不要忘记释放内存。

malloc 的优点是它尝试在堆而不是堆栈上分配内存(因此不会出现堆栈溢出)。

您可以检查 malloc 返回的值以查看分配是成功还是失败。如果失败,只需尝试 malloc 一个较小的数组。


另一种选择是使用可以动态调整大小的不同数据结构(如链表)。此选项是否合适取决于您要对数据执行的操作。

另一种选择是将内容存储在文件中,即时流式传输数据。这种方法是最慢的。

如果您在硬盘驱动器上进行存储,则不妨使用现有库(用于数据库)

于 2016-07-04T06:01:51.380 回答
0

由于 Turbo C/C++ 是 16 位编译器 int 数据类型,因此消耗大约 2 个字节。2bytes*2000000=40,00,000 bytes=3.8147MB 空间。

函数的自动变量存储在堆栈中,导致堆栈内存溢出。而是使用数据内存 [使用静态或全局变量] 或动态堆内存 [使用 malloc/calloc] 根据处理器内存映射的可用性创建所需的内存。

于 2017-07-13T20:02:40.277 回答
-1

有什么原因不能使用 alloca() 根据对象真正需要的大小在堆栈帧上分配所需的空间?

如果你这样做了,但仍然破坏了堆栈,请将其放入已分配的堆中。我强烈建议不要在 main() 中将其声明为静态并将其放入数据段中。

如果它真的必须那么大并且你的程序不能在堆上分配它,那么你的程序一开始就真的没有业务在那种类型的机器上运行。

你(确切地)想要完成什么?

于 2009-02-21T08:46:13.573 回答