double *Array = NULL;
This is fine (as long as you've included a header that defines NULL before you write it).
Array = malloc(dim1 * dim2 * sizeof(double));
You say this yields:
Error: Conflicting types for Array
Error: Initializer element is not constant
That is because the compiler is bending over backwards to accept your code, and manages to interpret the Array as an 'implicit int' variable, as if you wrote:
int Array = ...
Since int is not the same as double *, it gives you the conflicting types error.
The second message tells you that the initializer - the call to malloc() - is not a constant, and initializers outside functions must be constants. If you placed the line inside a function, then you'd have an assignment (not an initializer), and the code would be OK, though better written as:
if (Array == NULL)
Array = malloc(dim1 * dim2 * sizeof(double));
You should be compiling with more stringent compilation warnings. I get:
$ cat x.c
#include <stdlib.h>
double *Array = NULL;
Array = malloc(23 * 37 * sizeof(double));
$ gcc -g -std=c99 -pedantic -Wall -Werror -c x.c
x.c:3:1: error: data definition has no type or storage class [-Werror]
x.c:3:1: error: type defaults to ‘int’ in declaration of ‘Array’ [-Werror]
x.c:3:1: error: conflicting types for ‘Array’
x.c:2:9: note: previous definition of ‘Array’ was here
x.c:3:9: error: initialization makes integer from pointer without a cast [-Werror]
x.c:3:1: error: initializer element is not constant
cc1: all warnings being treated as errors
$