my problem is with freeing a dynamic 2D array, that's inside linked list
typedef struct name{
    char **given_name;
    char **surname;
} Name;
typedef struct list {
    float id;
    struct name author_name;
    struct list *p_prev, *p_next;
} List;
void load_data(List** head){
     List* tmp_new = Null;
     while(1){
          tmp_new->author_name.given_name= (char**) malloc(10 * sizeof(char*));
          tmp_new->author_name.surname   = (char**) malloc(10 * sizeof(char*));
          while(condition){ //this condition is always whithin 1-10
               tmp_new->author_name.given_name[i]=(char*) malloc(200 * sizeof(char*));
               tmp_new->author_name.surname[i]   =(char*) malloc(200 * sizeof(char*));
         }
          given_name= "John"
          surname= "Blake"
          sscanf(name, "%s %s", tmp_new->author_name.given_name[i], tmp_new->author_name.surname[i]);
  
          tmp_new->p_prev = *head;
          tmp_new->p_next = NULL;
          (*head)->p_next = p_new;
          (*head) = p_new;
          // realloc again for the next enrty
         
           given_name= "Tom"
           surname= "Jerry"
          sscanf(name, "%s %s", tmp_new->author_name.given_name[i],tmp_new->author_name.surname[i]);
      }
     }
//once done within this function free it
if(*head != NULL) {
            while (1){
                if ((*head)->p_next!= NULL) {
                    tmp = (*head);
                    (*head) = (*head)->p_next;
                    for(int i=0; i<200; i++){
                            free(tmp->author_name.given_name[i]);
                            free(tmp->author_name.surname[i]);
                            }
                    free(tmp->author_name.given_name);
                    free(tmp->author_name.surname);
                    free(tmp);
                    }
                else {
                    break;
                }
            }
        }
}
int main()
    List* head = NULL;
    List* tmp;
    load_data(&head);
    if (head != NULL) {
        while (1){
            if (head->p_next!= NULL) {
                 tmp = head;
                 head = head->p_next;
                     for(int i=0; i<200;i++){     
                         free(tmp->author_name.given_name[i])   
                         free(tmp->author_name.surname[i])                             
                            }
                           free(tmp->author_name.given_name);
                           free(tmp->author_name.surname);
                           free(tmp);
                        }
                        else {
                            printf("free was sucesfull.\n");
                            break;
                        }
                    }
                }
                return 0;
   
whenever i try to free the ///(tmp->author_name.given_name[i]) or /// tmp->author_name.surname[i]) i get segmentation faults, i put inside printf to see where it would break and it even breaks on 0 index, which is always full, so the problem isn't that while condition that's within 1-10, have no idea what might be happening, maybe I'm doing something wrong with pointer arithmetic? and needs to be freed differently :/
