[英]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
.您有一个名为Jsize
的int
对象,初始化为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.乘以一个int
由int
总是产生一个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.) (在我的系统上, calloc
因ENOMEM
失败,但我没有你那么多的内存。)
Note, however, that the OS might not let you allocate that much memory for one process.但是请注意,操作系统可能不允许您为一个进程分配那么多内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.