where are the memory leaks?
#include "friends.h"  
    #include <string.h>  
    #include <stdio.h>  
    #include <stdlib.h>  
    void remove_friend(User *user, const char *friend_name);  
    /* 
     * 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) {  
        User *curr = *user_ptr_add;  
      
        //first, check if user with same name exists  
        while(curr != NULL){  
            if (strcmp(curr->name, name) == 0){  
                return 1;  
            }  
            curr = curr->next;  
        }  
      
        // next, check if the name cannot fit in the 'name' array  
        // the '-1' reserves space for the null terminator  
        if (strlen(name) >= MAX_NAME - 1){  
            return 2;  
        }  
      
        // create a new user and add it to the end of the list  
        User *new_user = (User *)malloc(sizeof(User));  
        strcpy(new_user->name, name);  
        new_user->next = NULL;  
      
        // reset the current pointer  
        curr = *user_ptr_add;  
        if (curr == NULL) {  
            *user_ptr_add = new_user;  
        }  
        else {  
            while (curr->next != NULL){  
                curr = 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) {  
        // initialize the head of the linked list  
        const User *curr = head;  
      
        while (curr != NULL) {  
            // if match is found, return the user  
            if (strcmp(curr->name, name) == 0){  
                return (User *)curr;  
            }  
            curr = curr->next;  
        }  
        // end of the list was reached without finding user  
        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) {  
        // formatted like the sample output  
        printf("User List\n");  
        while (curr != NULL) {  
            // indent  
            printf("        ");  
            // name  
            printf("%s\n", curr->name);  
            curr = 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) {  
        // check if the file name is too long  
        if (strlen(filename) >= sizeof(user->profile_pic) - 1){  
            return 2;  
        }  
      
        // declare FILE variable like in PCRS prep (week 3)  
        FILE *file;  
        file = fopen(filename, "r");  
        // check if failed to be opened  
        if (file == NULL){  
            return 1;  
        }  
      
        // can use unsafe strcpy since the filename can fit  
        // close the file that opened successfully  
        strcpy(user->profile_pic, filename);  
        fclose(file); 
        free(file); 
        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) {  
        // find the users  
        User *user1 = find_user(name1, head);  
        User *user2 = find_user(name2, head);  
        //check if at least one user doesn't exist  
        if (!user1 || !user2){  
            return 4;  
        }  
      
        // check if the users are equal  
        else if (user1 == user2){  
            return 3;  
        }  
      
        // initialize the number of friends each user has  
        int user1_friends = 0;  
        int user2_friends = 0;  
      
        // loop counts the number of friends each user has to see if they  
        // exceed the maximum number of friends  
        for (int i = 0; i < MAX_FRIENDS; i++) {  
            if (user1->friends[i] != NULL) {  
                user1_friends++;  
            }  
            if (user2->friends[i] != NULL) {  
                user2_friends++;  
            }  
        }   
        if (user1_friends == MAX_FRIENDS || user2_friends == MAX_FRIENDS) {  
            return 2;  
        }  
      
        // checks if the users are already friends  
        for (int j = 0; j < MAX_FRIENDS; j++) {  
            if (user1->friends[j] == user2) {  
                return 1;  
            }  
        }  
      
        // otherwise, adds the users to each of their firends  
        for (int i = 0; i < MAX_FRIENDS; i++) {  
            if (user1->friends[i] == NULL) {  
                user1->friends[i] = user2;  
                break;  
            }  
        }  
        for (int i = 0; i < MAX_FRIENDS; i++) {  
            if (user2->friends[i] == NULL) {  
                user2->friends[i] = user1;  
                break;  
            }  
        }  
        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) {  
        // check if user is NULL  
        if (user == NULL) {  
            return 1;  
        }  
      
        // check if there is a profile pic associated with the user  
        if (strlen(user->profile_pic) != 0){  
            // open the profile pic  
            FILE *fptr;  
            fptr = fopen(user->profile_pic, "r");  
            if (fptr == NULL){  
                printf("Cannot open file \n");  
            }  
        
            // Read contents from file and print them   
            char pic = fgetc(fptr);  
            while (pic != EOF){  
                printf ("%c", pic);  
                pic = fgetc(fptr);  
            }  
        printf("\n");  
        }// print name  
        printf("Name: %s\n", user->name);  
        printf("------------------------------------------\n");  
      
        // print each friend in order in which they became friends  
        printf("Friends:\n");  
        for (int i = 0; i < MAX_FRIENDS; i++) {  
            User *friend = user->friends[i];  
            if (friend != NULL) {  
                printf("%s\n", friend->name);  
            }  
        }  
        printf("------------------------------------------\n");  
      
        printf("Posts:\n");  
        Post *current_post = user->first_post;  
        while (current_post != NULL) {  
            printf("From: %s\n", current_post->author);  
            // convert time_t to a string  
            printf("Date: %s", ctime(current_post->date));  
            // checks if post is the last to see if "===" is needed  
            if (current_post->next == NULL){  
                printf("\n%s\n", current_post->contents);  
            }  
            else {  
                printf("\n%s\n\n===\n\n", current_post->contents);  
            }  
            current_post = current_post->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 || !target) {  
            return 2;  
        }  
      
        // numerical Boolean to make predicate logic easy  
        int areFriends = 0;  
        for (int i = 0; i < MAX_FRIENDS; i++) {  
            if (target->friends[i] == author) {  
                areFriends = 1;  
                break;  
            }  
        }  
      
        if (!areFriends) {  
            return 1;  
        }  
        // allocate space for a new post  
        Post *newPost = (Post*)malloc(sizeof(Post));  
        strcpy(newPost->author, author->name);  
        newPost->contents = contents;  
        // allocate space for the time  
        time_t *now = (time_t*)malloc(sizeof(time_t));  
        time(now);  
        newPost->date = now; 
        free(now); 
        newPost->next = target->first_post;  
        target->first_post = newPost; 
        free(newPost); 
          
        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) {  
        User *curr = *user_ptr_del;  
        User *prev = NULL;  
      
        while (curr != NULL) {  
            // found the user to delete  
            if (strcmp(curr->name, name) == 0) {  
                // update pointers to skip over this user  
                if (prev != NULL) {  
                    prev->next = curr->next;  
                } else {  
                    *user_ptr_del = curr->next;  
                }  
      
                // remove this user from their friends' lists of friends  
                for (int i = 0; i < MAX_FRIENDS; i++) {  
                    if (curr->friends[i] != NULL) {  
                        remove_friend(curr->friends[i], curr->name);  
                    }  
                }  
      
                // free memory associated with this user  
                free(curr);  
      
                return 0;  
            }  
            prev = curr;  
            curr = curr->next;  
        }  
      
        // user not found  
        return 1;  
    }  
      
    void remove_friend(User *user, const char *friend_name) {  
        int i = 0;  
      while (i < MAX_FRIENDS && user->friends[i] != NULL) {  
        if (strcmp(user->friends[i]->name, friend_name) == 0) {  
          // Shift the rest of the elements in the friends array to fill the gap  
          for (int j = i; j < MAX_FRIENDS - 1; j++) {  
            user->friends[j] = user->friends[j + 1];  
          }  
          // Mark the last element in the array as NULL  
          user->friends[MAX_FRIENDS - 1] = NULL;  
          break;  
        }  
        i++;  
      }  
    }  