【发布时间】:2014-03-31 03:50:58
【问题描述】:
感谢您抽出宝贵时间阅读本文。我已经学习了几天 C 并且卡住了。我正在尝试创建巨大的数组(几 GB),但似乎无法创建大于 2GB 的数组。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* Exploring 1d array sizes in c */
int main()
{
int i;
double mbs;
int arr_length = 260000000;
int arr_size = sizeof(double) * arr_length;
double *arr = malloc(arr_size);
for(i = 0; i < arr_length; i++)
arr[i] = (double)i;
/* Print array size */
arr_size = (double)arr_size;
mbs = (double)arr_size / pow(1024.0, 2);
printf("The size of the array is %1.1f megabytes. \n", mbs);
return 0;
}
当我运行代码时,我得到了一个合理的结果:
:~/c-examples> gcc -o array-size array-size2.c
:~/c-examples> ./array-size
The size of the array is 1983.6 megabytes.
但是,如果我将 arr_length 增加到 270000000(2.7 亿),即使数组大小刚刚超过 2GB,也会出现分段错误。我目前正在运行 64 位 OpenSuse 13.1,并且有 6GB 的 RAM:
:~/c-examples> free -h
total used free shared buffers cached
Mem: 5.6G 910M 4.7G 27M 12M 377M
-/+ buffers/cache: 520M 5.1G
Swap: 2.0G 307M 1.7G
我希望最终能够存储大小为 10-12GB 的数组(在添加更多 RAM 之后),但想确保我完全了解之前发生的情况。再次感谢您的宝贵时间 - 欢迎提出建议(批评!)。
【问题讨论】:
-
你确定你的 GCC 也是 64 位的吗? 64 位操作系统不一定等同于 64 位编译器,因为我的 64 位 Win7 设置和 32 位 MinGW GCC 可以证明。如果您的 GCC 正在创建 32 位版本,则将适用 32 位限制。
-
这真的感觉像是一个与在 32 位上编译相关的问题,因为 2**32 == 4.3G,如果你在某处使用 int 而不是 uint,它将被完全最大化2.15G
-
问题是,当您将 arr_length 更改为 270000000 时,arr_size 超出了最大 32 位正整数值,最终将负大小传递给 malloc,然后将返回 NULL。如果您将 arr_size 的声明从“int”更改为“size_t”,您将看到您可以成功分配所需的内存。
-
感谢您的所有 cmets,arr_size 确实被错误地定义为 int,我为错过这一点感到很愚蠢。再次感谢!
-
BTW:当代码打印 size_t 时,使用
size_t sz; printf("%zu\n", sz);