在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中的堆栈上分配一个大数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在堆栈上分配数组时出现运行时错误[重复]

静态成员存储在内存中的啥位置? C#.Net中的堆栈/堆[重复]

C中的内联字符串数组是不是分配在堆栈上?

如何处理 C 中的堆栈数组分配失败?

堆栈和堆内存的大小[重复]

C - 堆栈分配的链表