If the size is known at compile time; you don't need to allocate anything; let the compiler take care of it (no malloc(), no free())
Now, if you want a 2D array of int, and the dimensions are not known at compile time, here's a way to do it. Suppose we want an array[size_x][size_y] of int, wheresize_x and size_y are variables. The "array" name will be a "pointer to a pointer to an int".
Here's an example (I have given size_x and size_y specific values for purposes of illustration, but these could be obtained from user input or from other program calculations, or whatever.)
C++ Programmers: Do the same, but use new and delete instead of malloc() and free().