我正在尝试使用calloc函数分配内存,但是当数组大小(类型double)为48,000 x 48,000时,它将返回NULL指针。但是,它对于23,000 x 23,000的另一种情况非常适用。从技术上讲应该没有问题,因为这台计算机上的RAM足够多。我也在使用64位库。
操作系统:Linux 64bit
安装的内存:376GB
编译器:Intel MKL 2019
编译器链接行:
icc Main.c -qopenmp -DMKL_ILP64 -m64 -I$MKLROOT/include \
-L$MKLROOT/lib/intel64 -lmkl_intel_ilp64 -lmkl_intel_thread \
-lmkl_core -liomp5 -lpthread -lm -ldl -O2 -o main.out
Run Code Online (Sandbox Code Playgroud)
这是我使用的一段代码:
int Jsize = 48000;
double *J = NULL;
J = (double *)calloc(Jsize*Jsize, sizeof(double));
if (J == NULL) printf("Null\n");
Run Code Online (Sandbox Code Playgroud)
您有一个int名为Jsize,初始化为48000 的对象Jsize*Jsize。然后进行计算。该表达式的数学值为2304000000,超过2 31 -1。
int您的系统上的类型几乎肯定是32位,这意味着乘法将溢出。该行为是不确定的,但很可能会得到负面结果。
请记住,C语言中表达式的类型由表达式本身而不是由求值上下文确定。即使将结果与更大的值相乘int,int总会得到一个int结果。
然后将该值作为第一个参数传递给calloc(),该参数需要一个类型的参数size_t。如果size_t是64位(这很可能如此),那么你传递一个巨大的正值,也许18446744071718584320如果我的计算是正确的。
在我的64位Ubuntu系统上,当我printf向您的代码添加几个调用时,我得到:
Jsize*Jsize = -1990967296
(size_t)(Jsize*Jsize) = 18446744071718584320
Null
Run Code Online (Sandbox Code Playgroud)
你没有那么多的记忆。
如果Jsize使用type 定义size_t,则至少可以尝试分配所需的17+ GiB。(在我的系统上,出现calloc失败ENOMEM,但我的RAM不如您那么多。)
但是请注意,操作系统可能不允许您为一个进程分配那么多的内存。