where is there a memory leak

#include "friends.h"  
#include <string.h>  
#include <stdio.h>  
#include <stdlib.h>  
  
/* 
 * Create a new user with the given name.  Insert it at the tail of the list 
 * of users whose head is pointed to by *user_ptr_add. 
 * 
 * Return: 
 *   - 0 if successful 
 *   - 1 if a user by this name already exists in this list 
 *   - 2 if the given name cannot fit in the 'name' array 
 *       (don't forget about the null terminator) 
 */  
int create_user(const char *name, User **user_ptr_add) {  
    //check if name is too long  
    if (strlen(name) > MAX_NAME - 1) {  
        return 2;  
    }  
  
    //Seperate case if linked list is empty  
    if (*user_ptr_add == NULL){  
        User *new_user = malloc(sizeof(User));  
    strcpy(new_user->name, name);  
    for (int i = 0; i < MAX_FRIENDS; i ++){  
        new_user->friends[i] = NULL;  
    }  
    new_user->first_post = NULL;  
    //make user head of the list  
    *user_ptr_add = new_user;  
    new_user->next = NULL;  
  
    strcpy(new_user->profile_pic, "empty_pic");  
    return 0;  
    }  
    // Traverse to end of linked_list; Compare usernames  
    User *curr = *user_ptr_add;  
    while (curr->next != NULL) {  
        if (strcmp(curr->name, name) == 0) {  
        return 1;  
    }  
    curr = curr->next;  
    }   
      
    //special case where user already exists at end of list  
    if (strcmp(curr->name, name) == 0) {  
    return 1;  
    }  
      
    // Declare new User object  
    User *new_user = malloc(sizeof(User));  
      
    //Initialize members of new_user  
    strcpy(new_user->name, name);  
    for (int i = 0; i < MAX_FRIENDS; i ++){  
        new_user->friends[i] = NULL;  
    }  
    new_user->first_post = NULL;  
    strcpy(new_user->profile_pic, "empty_pic");  
      
      
    //Now curr points to the tail  
    new_user->next = curr->next;  
    curr->next = new_user;  
  
    return 0;  
}  
  
  
/* 
 * Return a pointer to the user with this name in 
 * the list starting with head. Return NULL if no such user exists. 
 * 
 * NOTE: You'll likely need to cast a (const User *) to a (User *) 
 * to satisfy the prototype without warnings. 
 */  
User *find_user(const char *name, const User *head) {  
    if (head == NULL) {  
    return NULL;  
    }  
    User *curr = (User *) head;  
    while (curr != NULL) {  
        if (strcmp(name, curr->name) == 0) {  
        return curr;  
    }  
    curr = curr->next;  
    }  
    return NULL;  
}  
  
  
/* 
 * Print the usernames of all users in the list starting at curr. 
 * Names should be printed to standard output, one per line. 
 */  
void list_users(const User *curr) {  
    User *new_curr = (User *) curr;  
    while (new_curr != NULL) {  
        printf("%s\n", new_curr->name);  
    new_curr = new_curr->next;  
    }  
}  
  
  
/* 
 * Change the filename for the profile pic of the given user. 
 * 
 * Return: 
 *   - 0 on success. 
 *   - 1 if the file does not exist or cannot be opened. 
 *   - 2 if the filename is too long. 
 */  
int update_pic(User *user, const char *filename) {  
    FILE *test_exists;  
    test_exists = fopen(filename, "r");  
    if (strlen(filename) > MAX_NAME){  
        return 2;  
    } else if (test_exists == NULL){  
        return 1;  
    } else {  
    strcpy(user->profile_pic, filename);  
    if (fclose(test_exists) != 0){  
        return 1;  
    }  
    return 0;  
    }      
}  
  
  
/* 
 * Make two users friends with each other.  This is symmetric - a pointer to 
 * each user must be stored in the 'friends' array of the other. 
 * 
 * New friends must be added in the first empty spot in the 'friends' array. 
 * 
 * Return: 
 *   - 0 on success. 
 *   - 1 if the two users are already friends. 
 *   - 2 if the users are not already friends, but at least one already has 
 *     MAX_FRIENDS friends. 
 *   - 3 if the same user is passed in twice. 
 *   - 4 if at least one user does not exist. 
 * 
 * Do not modify either user if the result is a failure. 
 * NOTE: If multiple errors apply, return the *largest* error code that applies. 
 */  
int make_friends(const char *name1, const char *name2, User *head) {  
    //First, check if users dont exist  
    User *curr = head;  
    User *user1;  
    User *user2;  
    int found1 = 0;  
    int found2 = 0;  
    while (curr != NULL) {  
        if (strcmp(name1, curr->name) == 0){  
            found1 = 1;  
            user1 = curr;  
        } else if (strcmp(name2, curr->name) == 0){  
            found2 = 1;  
            user2 = curr;  
        }  
        curr = curr->next;  
    }  
    if (found1 == 0 || found2 == 0) {  
        return 4;  
    }  
  
    //Second, check if same user is passed in twice  
    if (strcmp(name1, name2) == 0){  
        return 3;  
    }  
      
    //Third, check if either of them has MAX_FRIENDS  
    int not_full1 = 0;  
    int not_full2 = 0;  
    for (int i = 0; i < MAX_FRIENDS; i ++) {  
        if (user1->friends[i] == NULL) {  
            not_full1 = 1;  
    }  
    if (user2->friends[i] == NULL) {  
        not_full2 = 1;  
    }  
    }  
    if (not_full1 == 0 || not_full2 == 0) {  
        return 2;  
    }  
      
    //Fourth, check if already friends  
    for (int i = 0; i < MAX_FRIENDS; i ++) {  
    if (user1->friends[i] != NULL) {  
        if (strcmp((user1->friends[i])->name, user2->name) == 0) {  
        return 1;  
        }  
        }  
    }  
  
    //Make friends  
    int index1 = 0;  
    int index2 = 0;  
    while (index1 < MAX_FRIENDS) {  
        if (user1->friends[index1] == NULL) {  
        user1->friends[index1] = user2;  
        break;  
    } else {  
        index1 ++;  
    }  
    }  
  
    while (index2 < MAX_FRIENDS) {  
        if (user2->friends[index2] == NULL) {  
        user2->friends[index2] = user1;  
        break;  
    } else {  
        index2 ++;  
    }  
    }  
    return 0;  
}  
  
  
/* 
 * Print a user profile. 
 * For an example of the required output format, see the example output 
 * linked from the handout. 
 * Return: 
 *   - 0 on success. 
 *   - 1 if the user is NULL. 
 */  
int print_user(const User *user) {  
    if (user == NULL) {  
        return -1;  
    }  
    //print profile pic  
    FILE *pfp = fopen(user->profile_pic, "r");  
    if (pfp != NULL) {  
        char line[61];  
    while (fgets(line, 61, pfp) != NULL) {  
        printf("%s", line);  
    }  
    printf("\n");  
    }  
                 
    //print name  
    printf("Name: %s\n", user->name);  
    printf("------------------------------------------\n");  
      
    //print friends  
    printf("Friends: \n");  
    int i = 0;  
    while (user->friends[i] != NULL && i < MAX_FRIENDS) {  
        printf("%s\n", (user->friends[i])->name);  
    i ++;  
    }  
    printf("------------------------------------------\n");  
    printf("Posts: \n");  
    //print posts  
    if (user->first_post != NULL) {  
        printf("From: %s\n", (user->first_post)->author);  
        printf("Date: %s\n", ctime((user->first_post)->date));  
        printf("%s\n", (user->first_post)->contents);  
  
        if ((user->first_post)->next != NULL){  
            Post *curr = (user->first_post)->next;  
            while (curr != NULL) {  
                printf("\n===\n\n");  
                printf("From: %s\n", curr->author);  
                printf("Date: %s\n", ctime(curr->date));  
                printf("%s\n", curr->contents);                
                curr = curr->next;  
            }  
        }  
    }  
    printf("------------------------------------------\n");  
    return 0;  
}  
  
  
/* 
 * Make a new post from 'author' to the 'target' user, 
 * containing the given contents, IF the users are friends. 
 * 
 * Insert the new post at the *front* of the user's list of posts. 
 * 
 * 'contents' is a pointer to heap-allocated memory - you do not need 
 * to allocate more memory to store the contents of the post. 
 * 
 * Return: 
 *   - 0 on success 
 *   - 1 if users exist but are not friends 
 *   - 2 if either User pointer is NULL 
 */  
int make_post(const User *author, User *target, char *contents) {  
    if (author == NULL || target == NULL) {  
    free(contents);  
        return 2;  
    }  
      
    //check if users are friends  
    int i = 0;  
    int is_friend = 0;  
    while (author->friends[i] != NULL) {  
        if (strcmp((author->friends[i])->name, target->name) == 0) {  
        is_friend = 1;  
        break;  
    }  
    i ++;  
    }  
    if (is_friend == 0) {  
        free(contents);  
    return 1;  
    } else {  
    //create and insert post at beginning of post linked list  
    Post *new_post = malloc(sizeof(Post));  
    strcpy(new_post->author, author->name);  
    new_post->contents = contents;  
    time_t *ct = malloc(sizeof(time_t));  
    time(ct);  
    new_post->date = ct;  
      
    if (target->first_post == NULL) {  
        new_post->next = NULL;  
        target->first_post = new_post;  
    } else {  
        new_post->next = target->first_post;  
        target->first_post = new_post;  
    }  
      
    }  
    return 0;  
}  
  
  
/* 
 * From the list pointed to by *user_ptr_del, delete the user 
 * with the given name. 
 * Remove the deleted user from any lists of friends. 
 * 
 * Return: 
 *   - 0 on success. 
 *   - 1 if a user with this name does not exist. 
 */  
int delete_user(const char *name, User **user_ptr_del) {  
    //first, find user and free memory from all their posts  
    User *del_user = find_user(name, *user_ptr_del);  
    if (del_user == NULL) {  
    return 1;  
    }  
    Post *curr_post = del_user->first_post;  
    while (curr_post != NULL) {  
    Post *prev = curr_post;  
    curr_post = curr_post->next;  
        free(prev->date);  
    free(prev);  
    }  
      
    //second, find user before the user to delete, and remove user to delete from linked_list  
    User *curr_user = *user_ptr_del;  
      //check if the user to delete is the head of the linked list  
    if (strcmp(curr_user->name, name) == 0) {  
    *user_ptr_del = curr_user->next;  
    del_user->next = NULL;  
    } else {  
        while (strcmp((curr_user->next)->name, name) != 0) {  
            curr_user = curr_user->next;  
        }  
    curr_user->next = del_user->next;  
        del_user->next = NULL;  
    }  
      
    //third, delete user from friendslist of their friends  
    int i = 0;  
    while (del_user->friends[i] != NULL) {  
        User *curr_friend = find_user((del_user->friends[i])->name, *user_ptr_del);  
    int j = 0;  
    while (strcmp((curr_friend->friends[j])->name, name) != 0) {  
        j ++;  
    }  
      
    curr_friend->friends[j] = NULL;  
    i ++;  
    }  
  
    //fourth, free memory allocated for user  
    free(del_user);        
  
    return 0;  
}  