在C中的堆栈上分配一个大数组

2 c memory arrays

我有以下程序:

#include <stdio.h>
#include <sys/resource.h>

int main()
{

    // Anything over ~8MB fails
    short int big[4000000];
    printf("%lu\n", sizeof(big));

}
Run Code Online (Sandbox Code Playgroud)

ulimit表明我的程序有无限的可用内存。但是,如果我尝试分配更多的内存,则会出现错误:

short int big[6000000];
$ gcc main.c -o main.out && ./main.out
Segmentation fault: 11
Run Code Online (Sandbox Code Playgroud)

我需要在C程序中进行任何更改,以便分配例如1GB的阵列吗?

Mar*_*lli 5

您是在堆栈上静态分配一个数组,这意味着编译器将编写代码来保留该空间,并且在main()调用您的代码时,它将尝试将堆栈指针移出程序可用的映射堆栈区域。触摸堆栈会导致分段错误,这就是您所看到的。

您可以增加堆栈大小,但这不是那么简单,也不是可移植的,通常,在堆栈上分配这么大的数组是一种不好的做法,应该避免。要处理这么大的数组,您应该使用example动态分配它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;
}
Run Code Online (Sandbox Code Playgroud)

另外,请记住,在这种情况下您不能使用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);
// ...
Run Code Online (Sandbox Code Playgroud)