It is better to have dynamically allocated array in this case.
Again, why? Please assume that the compiler supports C99, since the obvious "it's not portable" prior to C99 is obvious.
int *array = malloc(i*sizeof(int)); // alloc enough memory for the array
A cleaner way to do this without listing the type twice is by using a quirk of the sizeof operator:
int *array = malloc(i * sizeof *array);
Because sizeof doesn't evaluate the expression given as an operand, you're not dereferencing the (at this point) uninitialized pointer. It's not so big of a deal in cases where you're declaring and allocating all in one statement, but consider cases where the type changes and you do the allocation elsewhere. Then you'd need to grep the code looking for any instance of sizeof(int) in reference to that variable and change the type.