可以使以下代码在以下代码段中执行if
条件的可能情况有哪些?就我而言,我无法解释执行if
语句的任何原因。
#include <stdio.h>
#include <stdlib.h>
void main(void){
int Nod = 1024 * 8; //Nod contains the number of nodes
double *MM; //MM is a square matrix it can contain very large number of data 10^10
MM = calloc(8 * Nod * 8 * Nod, sizeof(double));
if (MM == NULL)exit(0);
//then MM will then be passed to some other functions say
eigenvalue(MM);}
我正在使用在非常大的程序中进行此检查的FEM代码。有趣的是,当我运行代码时,它会显示异常行为。有时程序会在这里停止。有时它只是工作正常。值得一提的是,当程序以粗网格运行时,即当Nod
具有较少的节点数时,程序就可以正常工作。但是当使用精细网格时,程序崩溃不幸。该程序在具有128GB Ram的迷你工作站中运行。该程序占用1GB(左右)的RAM。
答案 0 :(得分:6)
两个明显的问题:
8 * Nod * 8 * Nod
的类型为int
,可能不够大(在您的平台上)来保存结果。您可能需要size_t Nod
。如果值不是常数,您可能需要检查溢出(可能是特定于平台的函数,例如GCC的__builtin_mul_overflow()
)。calloc()
的结果,而不检查它是否为NULL
。如果分配器找不到足够大的连续块,它将失败,你应该在继续之前测试它。从不忽略使用它来报告错误的库函数的返回值。
答案 1 :(得分:0)
从手册页:
The malloc() and calloc() functions return a pointer to the allocated memory that
is suitably aligned for any kind of variable. On error, these functions return
NULL. NULL may also be returned by a successful call to malloc() with a size of
zero, or by a successful call to calloc() with nmemb or size equal to zero.e here
现在在你的情况下,它不会分配零大小的内存,所以返回NULL的唯一原因是无法分配内存。 在您显示的片段中,您将分配4294967296个元素(1024 * 1024 * 64 * 64),其大小为双(8个字节),即32Gb的ram。 现在你的系统肯定有那么多的ram,但是在任何给定的时间它可能都没有在连续的可分配块中,所以calloc可能因为这个原因而失败。
需要注意的另一件事是内存过量使用主要由
决定/proc/sys/vm/overcommit_memory
or vis sysctl vm.overcommit_memory
默认情况下,overcommit_memory设置为0,但最安全的组合可能是将其设置为2.有关详细信息,请参阅proc手册页或内核Documentation / vm / overcommit-accounting。
vm.overcommit_ratio
vm.overcommit_kbytes
vm.nr_overcommit_hugepages
也是管理系统是否/如何处理内存过量使用的其他sysctl设置。
即使在此,我也尽力不允许在32位Linux机器上过度使用内存,但我仍然能够获得巨大的32Gb callot不返回null(我认为它很奇怪& #39;自己作为PAE少32位机器只能处理总共4Gb的虚拟内存,即使它有PAE,它也只允许一次寻址4Gb。