简体   繁体   English

使用“calloc”进行内存分配失败

[英]Memory Allocation with "calloc" Fails

I am trying to allocate memory using calloc function but when the array size (type double ) is 48,000 x 48,000 it returns NULL pointer.我正在尝试使用calloc函数分配内存,但是当数组大小(类型double )为 48,000 x 48,000 时,它返回 NULL 指针。 However, it works perfectly for another case which is 23,000 x 23,000.但是,它非常适用于 23,000 x 23,000 的另一种情况。 Technically there should be no problem because I have more than enough RAM on this computer.从技术上讲应该没有问题,因为我在这台计算机上有足够的 RAM。 I am also using the 64bit libraries.我也在使用 64 位库。

OS: Linux 64bit操作系统:Linux 64位

Installed memory: 376GB安装内存:376GB

Compiler: Intel MKL 2019编译器:英特尔 MKL 2019

Compiler link line:编译器链接行:

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

And here the piece of code that I use:这里是我使用的一段代码:

int Jsize = 48000;
double *J = NULL;
J = (double *)calloc(Jsize*Jsize, sizeof(double));
if (J == NULL) printf("Null\n");

You have an int object named Jsize , initialized to 48000. You then compute Jsize*Jsize .您有一个名为Jsizeint对象,初始化为Jsize然后计算Jsize*Jsize The mathematical value of that expression is 2304000000 , which exceeds 2 31 -1.该表达式的数学值为2304000000 ,超过 2 31 -1。

Type int on your system is almost certainly 32 bits, which means the multiplication will overflow.系统上的int类型几乎可以肯定是 32 位,这意味着乘法会溢出。 The behavior is undefined, but most likely you'll get a negative result.行为未定义,但很可能你会得到一个负面的结果。

Remember that the type of an expression in C is determined by the expression itself, not by the context in which it's evaluated.请记住,C 中表达式的类型由表达式本身决定,而不是由计算它的上下文决定。 Multiplying an int by an int always yields an int result, even if that result is assigned to something bigger.乘以一个intint总是产生一个int结果,即使结果被分配到更大的东西。

That value is then passed as the first argument to calloc() , which expects an argument of type size_t .然后将该值作为第一个参数传递给calloc() ,它需要一个size_t类型的参数。 If size_t is 64 bits (which it probably is), then you're passing a huge positive value, probably 18446744071718584320 if my calculations are correct.如果size_t是 64 位(它可能是),那么你传递了一个巨大的正值,如果我的计算是正确的,可能是18446744071718584320

On my 64-bit Ubuntu system, when I add a couple of printf calls to your code, I get:在我的 64 位 Ubuntu 系统上,当我向代码中添加几个printf调用时,我得到:

Jsize*Jsize = -1990967296
(size_t)(Jsize*Jsize) = 18446744071718584320
Null

You don't have that much memory.你没有那么多内存。

If you define Jsize with type size_t , you can at least try to allocate the 17+ GiB that you want.如果您使用size_t类型定义Jsize ,则至少可以尝试分配所需的 17+ GiB。 (On my system, calloc fails with ENOMEM , but I don't have as much RAM as you do.) (在我的系统上, callocENOMEM失败,但我没有你那么多的内存。)

Note, however, that the OS might not let you allocate that much memory for one process.但是请注意,操作系统可能不允许您为一个进程分配那么多内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM