From the man page:
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
Now in your case it's not dew to allocating zero sized memory so the only other reason for returning NULL is failure to allocate the memory.
In the snippet you show you are allocating 4294967296 elements (1024 * 1024 * 64 * 64) the size of a double (8 bytes) that's 32Gb of ram.
Now your system definitely has that amount of ram but at any given time it may not have it all in a consecutive allocable block so calloc may be failing for that reason.
Another thing to watch out for is memory overcommitment governed primarily by
/proc/sys/vm/overcommit_memory
or vis sysctl vm.overcommit_memory
by default overcommit_memory is set to 0 but possibly the safest combination would be setting it to 2. See proc man page or kernel Documentation/vm/overcommit-accounting for more detail on this.
vm.overcommit_ratio
vm.overcommit_kbytes
vm.nr_overcommit_hugepages
are also other sysctl settings that govern if/how your system will deal with memory overcommitment.
Even at this I've done my best not to allow overcommitment of memory on a 32 bit linux machine but I was still able to get the huge 32Gb callot not to return null (which I regard as being strange on it's own as a PAE less 32 bit machine can only address a total of 4Gb of virtual memory, and even if it had PAE it would only allow addressing 4Gb at a time).