Following on from the comments, there are a number of issues you have in your code. First gets, don't use it, it is a 'hanging' offense -- enough said.
Next, validate all user input. For all you know, a cat could be stepping on the keyboard. Make sure you test what you receive as input, and that it matches what you expect.
Mixing scanf with line-oriented input (e.g. fgets or getline can cause problems for new users. Why? The scanf family of functions do not remove the '\n' and instead leaves it in the input buffer (e.g. stdin). When you then attempt to read with fgets the first character it sees in stdin is what? A '\n', which it reads and considers a whole line. If you are going to use scanf to read the number of strings, it is up to you to remove the '\n' that scanf left in stdin.
It's not hard, you can actually just use the assignment suppression operator provided by scanf in your format string. E.g.:
scanf ("%d%*c", &n);
The * is the assignment suppression operator, which when used with %*c simply tells scanf to read and discard the next character without adding to the match count (e.g. what scanf returns).
You will want to use a while loop instead of a for loop, (or use an independent index) when filling your array. Why? What if the users cancels input with a ctrl + d (or ctrl + z on windoze). If you are iterating up to n regardless of what the user does, you can easily attempt to index an array element that you haven't allocated, or allocate for a string that was not entered.
Putting it altogether, you can do something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXA = 20, MAXS = 40 }; /* max ptrs and str */
int main (void) {
    char *arr[MAXA] = {NULL}, str[MAXS] = "";
    int i = 0, n = 0, ndx = 0;   /* initialize all variables */
    printf ("enter the number of strings: ");
    /* use assignment suppression %*c to discard the \n */
    if (scanf ("%d%*c", &n) != 1) { /* always validate input */
        fprintf (stderr, "error: invalid integer input.\n");
        return 1;
    }
    if (n > MAXA) { /* validate the value of n */
        fprintf (stderr, "warning: n > %d, using %d as limit.\n",
                MAXA, MAXA);
        n = MAXA;
    }
    printf("Enter the strings\n");
    while (ndx < n && fgets (str, sizeof str, stdin)) { /* validate input */
        size_t len = strlen (str); /* get the length */
        if (str[len - 1] == '\n')  /* check for '\n' */
            str[--len] = 0;        /* overwrite with nul-terminator */
        if (!(arr[ndx] = malloc (len + 1))) { /* validate allocation */
            fprintf (stderr, "error: virtual memory exhausted.\n");
            break;
        }
        strcpy (arr[ndx], str);   /* copy to array */
        ndx++;                    /* increment index */
    }
    printf("\nThe Strings are:\n");
    for (i = 0; i < ndx; i++) {  /* you have ndx strings not n */
        printf (" arr[%2d] : %s\n", i, arr[i]);
        free (arr[i]);  /* free memory when no longer needed */
    }
    return 0;
}
Example Use/Output
$ ./bin/nogets
enter the number of strings: 3
Enter the strings
My dog
has a lot
of fleas.
The Strings are:
 arr[ 0] : My dog
 arr[ 1] : has a lot
 arr[ 2] : of fleas.
Now try the same thing and press ctrl + d instead of entering "of fleas." (you are covered).
Lastly, in any code your write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed. Get in the habit of tracking the memory you allocate, and free it rather than relying on it being done on exit. That will serve you well as your programs grow more complex.
Look over the code, and make sure you understand what is going on. Let me know if you have any questions.