No, the secondary arrays will not be freed automatically; you will need to explicitly free them before freeing listofdetails:
for ( i = 0; i < 6; i++ )
  free( listofdetails[i] );
free( listofdetails );
For every malloc there must be a free, and the free calls must be executed in the reverse order of the malloc calls.  
If the number of columns is known at compile time1, you can allocate the whole thing in one malloc call, like so:
char (*listofdetails)[40] = malloc( sizeof *listofdetails * 6 );  
This allocates a 6x40 array of char in a single call.  You'd use it pretty much the same way as you do above:
fgets( listofdetails[i], sizeof listofdetails[i], fp );
The type of listdetails[i] is "40-element array of char", so sizeof listdetails[i] will give us the same result as sizeof (char) * 40 (note that this only works because I declared listofdetails as a pointer to a 40-element array of char, not as a pointer to a pointer to char).  
This also has the advantage that all of the rows are adjacent to each other in memory, which may matter for some situations.  That's not necessarily the case for the 2-step allocation method.  
This only requires a single free call:
free( listofdetails );
but y'all probably aren't to the point of discussing pointers to arrays yet.
1.  If you're using a C99 compiler or a C2011 compiler that still supports variable-length arrays, you can still use the single malloc call like so:
size_t rows, cols;
...
char (*listofdetails[cols]) = malloc( sizeof *listofdetails * rows );
...
free( listofdetails );
Otherwise, you'll have to do the piecemeal allocation as in your code.