As far as good practice goes you should free everything you allocate, think of it like opening an html tag and closing it, and as far as good practices go it's a good idea not to think about structs the way you would about classes in C++ or java.
Freeing structs only free pointers to object, not the object itself,
#include <stdio.h>                                                                                                                                                                   
                                                                                                                                                                               
typedef struct                                                                                                                                                                       
{                                                                                                                                                                                    
    int a,b,c,d;                                                                                                                                                                     
    char some_string[1050];                                                                                                                                                          
                                                                                                                                                                                     
} first_type;                                                                                                                                                                        
typedef struct                                                                                                                                                                       
{                                                                                                                                                                                    
    struct first_type *ap;                                                                                                                                                           
} second_type;                                                                                                                                                                       
                                                                                                                                                                                                                                                                                                                                                                    
int main(void)                                                                                                                                                                       
{                                                                                                                                                                                    
    printf("first type: %d\n", sizeof(first_type));                                                                                                                                  
    printf("second type: %d\n", sizeof(second_type));                                                                                                                                
}          
if you run this little example you will see something like this
first type: 1068
second type: 8
although second_type has a pointer to a first_type it's size is considerably less than first_type. So when you malloc and free stuff you are only reserving and releasing however many bytes that data type is in memory.
Hope this helps.