Calloced内存似乎为NULL

时间:2017-03-13 09:42:53

标签: c dynamic-allocation calloc finite-element-analysis

可以使以下代码在以下代码段中执行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。

2 个答案:

答案 0 :(得分:6)

两个明显的问题:

  1. 计算8 * Nod * 8 * Nod的类型为int,可能不够大(在您的平台上)来保存结果。您可能需要size_t Nod。如果值不是常数,您可能需要检查溢出(可能是特定于平台的函数,例如GCC的__builtin_mul_overflow())。
  2. 您使用calloc()的结果,而不检查它是否为NULL。如果分配器找不到足够大的连续块,它将失败,你应该在继续之前测试它。
  3. 从不忽略使用它来报告错误的库函数的返回值。

答案 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。