在C中的堆栈上分配一个大数组[重复]
Posted
技术标签:
【中文标题】在C中的堆栈上分配一个大数组[重复]【英文标题】:Allocating a large array on the stack in C [duplicate] 【发布时间】:2020-01-05 02:35:49 【问题描述】:我有以下程序:
#include <stdio.h>
#include <sys/resource.h>
int main()
// Anything over ~8MB fails
short int big[4000000];
printf("%lu\n", sizeof(big));
ulimit
表明我有无限的内存可供程序使用。但是,如果我尝试分配更多内存,则会出现错误:
short int big[6000000];
$ gcc main.c -o main.out && ./main.out
Segmentation fault: 11
我需要在 C 程序中更改什么以便分配,例如 1GB 数组吗?
【问题讨论】:
Explanation of why allocating a large array results in segmentation fault in C, Segmentation fault on large array sizes, Why do I get a segfault in C from declaring a large array on the stack?, why does this large array declaration produce a segmentation fault? 【参考方案1】:您在堆栈上静态分配一个数组,这意味着编译器将编写代码来保留该空间,并且当您的 main()
被调用时,它将尝试将堆栈指针移出可用的映射程序的堆栈区域。触摸堆栈会导致分段错误,这就是您所看到的。
您可以增加堆栈大小,但这不是那么简单或可移植,而且通常在堆栈上分配如此大的数组 是不好的做法,应该避免。要处理这么大的数组,您应该动态分配它,例如使用malloc()
。
这是一个工作示例:
#include <stdio.h>
#include <stdlib.h>
int main(void)
short int *big;
big = malloc(6000000 * sizeof(short int));
if (big == NULL)
fputs("Failed to allocate memory!\n", stderr);
return 1;
// Do whatever...
free(big);
return 0;
另外,请记住,您不能在这种情况下使用sizeof()
,因为big
是一个动态分配的数组(sizeof(big)
将产生指针的大小,而不是实际大小大批)。这是因为sizeof()
是一个编译时运算符,只有在编译时知道大小时才能为您提供帮助。在这种情况下,它不是,因为空间是在运行时分配的。
如果你想知道那个数组的大小,你可以简单地用乘法计算它:
short int *big;
const size_t big_size = 6000000ULL * sizeof(short int);
printf("Size: %zu\n", big_size);
big = malloc(big_size);
// ...
【讨论】:
感谢您的详细回答。您能否解释一下关于sizeof()
的最后一部分以及应该改用什么?
@Shared 当然,添加到我的答案中。【参考方案2】:
#include <stdio.h>
#include <sys/resource.h>
int main()
// allocate the memory you need
short int* big = (short int*)malloc(6000000 * sizeof(short));
if(big)
printf("alloc all good\n");
// to free memory
free(big);
else
printf("alloc failed\n");
【讨论】:
【参考方案3】:您应该使用动态内存分配而不是静态定义一个数组来分配 1GB 的数据。This link will help you learn the difference
【讨论】:
【参考方案4】:您无法从统计上声明任何具有这么大尺寸的数组。它会导致程序堆栈溢出。您需要的是动态声明内存。而这里的链表可以达到你的目的。
【讨论】:
以上是关于在C中的堆栈上分配一个大数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章