即使我释放了每个malloc,动态结构数组和linkedlist中仍存在内存泄漏

即使我释放了每个malloc,动态结构数组和linkedlist中仍存在内存泄漏,c,arrays,memory,valgrind,C,Arrays,Memory,Valgrind,当我在我的项目上运行valgrind时,五分之四的分配没有被释放,我不知道为什么 我尝试去引用和释放似乎有问题的变量 #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_LINE 1000 #define INPUT_NUM 9 enum hobbies{BASEBALL=1, BASKETBALL, BICYCLE

当我在我的项目上运行valgrind时,五分之四的分配没有被释放,我不知道为什么

我尝试去引用和释放似乎有问题的变量

      #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    #define MAX_LINE 1000
    #define INPUT_NUM 9

    enum hobbies{BASEBALL=1, BASKETBALL, BICYCLE, BOOKS,
        DRAWING, GYM, MOVIES, POETRY};
    typedef struct User{
        char *ID, *firstName, *lastName, *userName, *password, *description;
        char sex, hobbies;
        int age;
    }User;

    typedef struct UserItem UserItem;
    struct UserItem{
        User* data;
        UserItem* next;
    };
    typedef struct{
        UserItem *head, *last;
    }UserList;

    typedef struct DynamicArray{
        int size;
        int capacity;
        User** array;
    }DynamicArray;

    typedef int(*Comparator)(User*, User);

    typedef enum {false, true} bool;


    void updateData(char *info[9], DynamicArray *dynamicArray, UserList **userList){
        //Male-Array
        if(info[4][0]=='M')
        {
            incrementArray(dynamicArray);
            dynamicArray->array[dynamicArray->size]=realloc(dynamicArray->array[dynamicArray->size],sizeof(User));
            newUser(info,dynamicArray->array[dynamicArray->size]);
            dynamicArray->size++;
        }
        //Female -Linked List
        else {
            User *user=malloc(sizeof(User));
            newUser(info,user);
            add(*userList,user);
        }
    }

    User* newUser(char* info[INPUT_NUM],User* user){
        user->ID=strdup(info[0]);
        if((user->firstName =(char*)malloc(strlen(info[1])+1))==NULL)
        {
            printf("error\n");
            exit(1);
        }
        strcpy(user->firstName,info[1]);
        if((user->lastName =(char*)malloc(strlen(info[2])+1))==NULL)
        {
            printf("error\n");
            exit(1);
        }
        strcpy(user->lastName,info[2]);
        user->age=atoi(info[3]);
        user->sex=*info[4];
        if((user->userName =(char*)malloc(strlen(info[5])+1))==NULL)
        {
            printf("error\n");
            exit(1);
        }
        strcpy(user->userName,info[5]);
        if((user->password =(char*)malloc(strlen(info[6])+1))==NULL)
        {
            printf("error\n");
            exit(1);
        }
        strcpy(user->password,info[6]);
        user->hobbies|=1<<(8-(*(info[7])-'0'));
        user->hobbies|=1<<(8-(*((info[7])+2)-'0'));
        user->hobbies|=1<<(8-(*((info[7])+4)-'0'));
        user->hobbies|=1<<(8-(*((info[7])+6)-'0'));
        if((user->description =(char*)malloc(strlen(info[8])+1))==NULL)
        {
            printf("error\n");
            exit(1);
        }
        strcpy(user->description,info[8]);
        return user;
    }

    void newUserList(UserList** list){
        *list=(UserList*)malloc(sizeof(UserList));
        if(*list==NULL){
            printf("error\n");
            exit(1);
        }
        (*list)->head=(UserItem*)malloc(sizeof(UserItem));
        (*list)->head->data=NULL;
        (*list)->head->next=NULL;
        (*list)->last=((*list)->head);
    }

    void newDynamicArray(DynamicArray *array){
        array->size=0;
        array->capacity=5;
        array->array=(User**)calloc((array->capacity),sizeof(User*));
    }


    void freeUser(User* user){
        if(user!=NULL){
            free(user->ID);
            free(user->firstName);
            free(user->lastName);
            free(user->userName);
            free(user->password);
            free(user->description);
        }
    }

    void freeUserItem(UserItem* item){
        if(item!=NULL){
            freeUser(item->data);
            freeUserItem(item->next);
            free(item);
            item=NULL;
        }
    }

    void freeUserList(UserList* list){
        freeUserItem(list->head);
    }

    void freeArray(DynamicArray *dynamicArray){
        int i;
        for (i=0;i<dynamicArray->capacity;i++){
            freeUser(dynamicArray->array[i]);
            free(dynamicArray->array[i]);
        }
        free(dynamicArray->array);
        dynamicArray->array=NULL;
    }

    void start(DynamicArray* dynamicArray, UserList* userList){
        FILE *input;
        int c,index;
        char line[MAX_LINE];
        char* info[INPUT_NUM];
        input = fopen("input.txt","rt");
        if(input) {
            while (EOF != (c = fgetc(input))) {
                ungetc(c, input);
                fgets(line, MAX_LINE, input);
                info[0] = strtok(line, ";");
                index = 1;
                while (index < INPUT_NUM) {
                    info[index] = strtok(NULL, ";");
                    index++;
                }
                updateData(info, dynamicArray, &userList);
            }
        }
        else
            exit(1);
        fclose(input);
    }

    int main() {
        int choice;
        DynamicArray dynamicArray;
        newDynamicArray(&dynamicArray);
        UserList* userList;
        newUserList(&userList);
        start(&dynamicArray, userList);
        bubbleSort(&userList, (Comparator) lastNameComparator);
        do{
            printf("Welcome! please choose an option\n"
                   "1 - Log in\n"
                   "2 - New member\n"
                   "3 – Exit\n");
            scanf("%d",&choice);
            switch(choice){
                case 1:
                    login(&dynamicArray, &userList);
                    break;
                case 2:
                    addNewMember(&dynamicArray, &userList);
                    break;
                case 3:
                    end(&dynamicArray,userList);
                    break;
                default:
                    printf("Bad choice, please try again\n");
                    break;
            }
        }while(choice!=3);
        return 0;
    }

    void end(DynamicArray* dynamicArray, UserList* userList){
       // FILE *output;
        //output=fopen("output.txt","w");
        //fclose(output);
        freeAllMemory(dynamicArray, userList);
    }

    void add(UserList *userList, User *newUser) {
        UserItem* item=(UserItem*)malloc(sizeof(UserItem));
        item->data=newUser;
        item->next=NULL;
        userList->last->next=item;
        userList->last=item;
        if(userList->head->data==NULL)
            userList->head=userList->last;
    }

    void login(DynamicArray* dynamicArray, UserList** userList){
        User* user;
        char username[10],password[15];
        printf("Please enter your username: \n");
        scanf("%s",username);
        user=usernameExists(username,*userList,dynamicArray);
        if(user==NULL){
            printf("User do not exist in the system, please try again \n");
            //Another try
            printf("Please enter your username: \n");
            scanf("%s",username);
            user=usernameExists(username,*userList,dynamicArray);
            if(user==NULL)
                return;
        }
        printf("Please enter your password: \n");
        scanf("%s",password);
        //Wrong password
        if(strcmp(password,user->password)!=0){
            printf("Wrong password\n");
            return;
        }
        //Login successful
        printf("Hello %s!\n", user->firstName);
        mainMenu(dynamicArray, userList, user);
    }

    void addNewMember(DynamicArray* dynamicArray, UserList** userList){
        char* info[INPUT_NUM];
        char id[9], tmp1[15], tmp2[10], age[3], sex, description[211];
        int i;
        //Prevent NULL
        for(i=0;i<INPUT_NUM;i++)//Prevent NULL
            info[i]="";
        printf("Please enter your ID: \n");
        //ID
        scanf("%s",id);
        if(idExists(id,dynamicArray,*userList)) {
            printf("Error: User already exists");
            return;
        }
        strcpy(id,info[0]);
        //First name
        printf("Please enter your first name:\n");
        scanf("%s",tmp1);
        if(strlen(tmp1)<3||(!containsOnlyLetters(tmp1)))
            return;
        strcpy(tmp1,info[1]);
        //Last name
        printf("Please enter your last name:\n");
        scanf("%s",tmp1);
        if(strlen(tmp1)<3||(!containsOnlyLetters(tmp1)))
            return;
        strcpy(tmp1,info[2]);
        //Age
        printf("Please enter your age (18 to 100):\n");
        scanf("%s",age);
        if (atoi(age)<18||atoi(age)>100)
            return;
        strcpy(age,info[3]);
        //Sex
        printf("Please enter your gender (F-female, M-male):\n");
        scanf("%c", &sex);//Dummy
        scanf("%c", &sex);
        if (sex!='M'&&sex!='F')
            return;
        info[4]=&sex;
        //Username
        printf("Choose a username (3-10 characters):\n");
        scanf("%s", tmp2);
        if(strlen(tmp2)<3||tmp2[0]<65||tmp2[0]>122||(tmp2[0]>=91&&tmp2[0]<=96))
            return;
        strcpy(tmp2,info[5]);
        printf("please choose 4 hobbies: Baseball=1, Basketball=2, Bicycle=3, Books=4,"
               " Drawing=5, Gym=6, Movies=7, Poetry=8\n");
        scanf(" %8[^\n]",tmp2);
        strcpy(tmp2,info[7]);
        printf("Choose a password (attention-minimum 3 characters):\n");
        scanf("%s",tmp1);
        if(strlen(tmp1)<3)
            return;
        strcpy(tmp1,info[6]);
        printf("Some words about yourself:\n");
        scanf(" %s",description);
        strcpy(description,info[8]);
        updateData(info,dynamicArray,userList);
        printf("Hi %s, lets find love!\n", info[1]);
        mainMenu(dynamicArray,userList,usernameExists(info[5],*userList,dynamicArray));
    }

    User* usernameExists(char *username, UserList *userList, DynamicArray *dynamicArray){
        int i;
        for (i=0;i<dynamicArray->size;i++)
            if(strcmp(dynamicArray->array[i]->userName,username)==0)
                return dynamicArray->array[i];
        UserItem* iterator = newIterator(userList);
        while(iterator!=NULL&&iterator->data!=NULL){
            if(strcmp(iterator->data->userName,username)==0)
                return iterator->data;
            iterator=iterator->next;
        }
        return NULL;
    }

    UserItem* newIterator (UserList* userList){
        return userList->head;
    }

    int idExists(char *ID, DynamicArray *dynamicArray, UserList *userList){
        int i=0;
        for (i=0;i<dynamicArray->size;i++)
            if(strcmp(dynamicArray->array[i]->ID,ID)==0)
                return 1;
        UserItem* iterator = newIterator(userList);
        while(iterator!=NULL&&iterator->data!=NULL){
            if(strcmp(iterator->data->ID,ID)==0)
                return 1;
            iterator=iterator->next;
        }
        return 0;
    }


    int containsOnlyLetters(char str[]){
        int i;
        for(i=0;i<strlen(str);i++)
            if(str[i]<65||str[i]>122||(str[i]>=91&&str[i]<=96))
                return 0;
        return 1;
    }

    void freeAllMemory(DynamicArray* dynamicArray, UserList* userList){
        freeArray(dynamicArray);
        freeUserList(userList);
    }

    void removeUserFromList(UserList* list, User* user){
        UserItem* iterator=newIterator(list);
        UserItem* previous=list->head;

        while(iterator!=NULL && iterator->data!=NULL && equal(iterator->data,user)== false){
            previous=iterator;
            iterator=iterator->next;
        }
        if(iterator!=NULL && iterator->data!=NULL && equal(iterator->data,user)== true){
            previous->next=iterator->next;
            iterator->next=NULL;
            freeUserItem(iterator);
            if(iterator==list->head) {
                list->head = NULL;
                list->last = NULL;
            }
            if(iterator==list->last)
                list->last=previous;
        }
    }

    bool equal(User* u1, User* u2){
        if(u1->ID==u2->ID)
            return true;
        return false;
    }

    void removeUserFromArray(DynamicArray* dynamicArray, User* user){
        int i,j,found=0;
        User  *tmp;
        //Find index
        for (i=0;i<dynamicArray->size;i++)
            if(strcmp(dynamicArray->array[i]->ID,user->ID)==0) {
                found = 1;
                break;
            }
        if(found) {
            tmp = dynamicArray->array[i];
            for (j = i; j + 1 < dynamicArray->size; j++) {
                dynamicArray->array[j] = dynamicArray->array[j+1];
            }
            freeUser(tmp);
            dynamicArray->size--;
        }
    }

    void deleteMe(DynamicArray* dynamicArray, UserList* list, User *user){
        removeUserFromArray(dynamicArray,user);
        removeUserFromList(list,user);
    }


    void incrementArray(DynamicArray *array){
        if(array->size>=array->capacity){
            array->capacity*=2;
           array->array=realloc(array->array, sizeof(User*)*array->capacity);
        }
    }
#包括
#包括
#包括
#定义最大线1000
#定义输入编号9
枚举爱好{棒球=1,篮球,自行车,书籍,
绘画、体操、电影、诗歌};
类型定义结构用户{
字符*ID、*firstName、*lastName、*userName、*password、*description;
性、爱好;
智力年龄;
}用户;
typedef struct UserItem UserItem;
结构用户项{
用户*数据;
UserItem*下一步;
};
类型定义结构{
UserItem*头,*尾;
}用户列表;
typedef结构DynamicArray{
整数大小;
国际能力;
用户**数组;
}动态卡雷;
typedef int(*比较器)(用户*,用户);
typedef枚举{false,true}bool;
void updateData(char*info[9],DynamicArray*DynamicArray,UserList**UserList){
//公阵列
如果(信息[4][0]=='M')
{
增量数组(dynamicArray);
dynamicArray->array[dynamicArray->size]=realloc(dynamicArray->array[dynamicArray->size],sizeof(User));
新用户(信息,动态卡片->数组[动态卡片->大小];
dynamicArray->size++;
}
//女性链表
否则{
User*User=malloc(sizeof(User));
新用户(信息,用户);
添加(*用户列表,用户);
}
}
用户*新用户(字符*信息[输入数量],用户*用户){
用户->ID=strdup(信息[0]);
如果((用户->名字=(字符*)malloc(strlen(信息[1])+1))==NULL)
{
printf(“错误\n”);
出口(1);
}
strcpy(用户->名字,信息[1]);
如果((用户->姓氏=(字符*)malloc(strlen(信息[2])+1))==NULL)
{
printf(“错误\n”);
出口(1);
}
strcpy(用户->姓氏,信息[2]);
用户->年龄=atoi(信息[3]);
用户->性别=*信息[4];
如果((用户->用户名=(字符*)malloc(strlen(信息[5])+1))==NULL)
{
printf(“错误\n”);
出口(1);
}
strcpy(用户->用户名,信息[5]);
如果((用户->密码=(字符*)malloc(strlen(信息[6])+1))==NULL)
{
printf(“错误\n”);
出口(1);
}
strcpy(用户->密码,信息[6]);
用户->爱好|=1data=NULL;
(*列表)->head->next=NULL;
(*列表)->last=((*列表)->head);
}
void newDynamicArray(DynamicArray*数组){
数组->大小=0;
阵列->容量=5;
数组->数组=(用户**)calloc((数组->容量),sizeof(用户*);
}
void freeUser(用户*用户){
如果(用户!=NULL){
免费(用户->ID);
免费(用户->名字);
免费(用户->姓氏);
免费(用户->用户名);
免费(用户->密码);
免费(用户->说明);
}
}
作废freeUserItem(UserItem*item){
如果(项!=NULL){
自由用户(项目->数据);
freeUserItem(项目->下一步);
免费(项目);
item=NULL;
}
}
作废freeUserList(UserList*list){
freeUserItem(列表->标题);
}
void freeArray(DynamicArray*DynamicArray){
int i;
对于(i=0;icapacity;i++){
freeUser(dynamicArray->array[i]);
free(dynamicArray->array[i]);
}
自由(动态卡雷->阵列);
dynamicArray->array=NULL;
}
无效开始(DynamicArray*DynamicArray,UserList*UserList){
文件*输入;
int c,索引;
字符行[最大行];
字符*信息[输入数量];
input=fopen(“input.txt”、“rt”);
如果(输入){
而(EOF!=(c=fgetc(输入))){
ungetc(c,输入);
fgets(线、最大线、输入);
info[0]=strtok(第“;”行);
指数=1;
while(索引<输入值){
info[index]=strtok(空,“;”);
索引++;
}
更新数据(信息、动态数据和用户列表);
}
}
其他的
出口(1);
fclose(输入);
}
int main(){
智力选择;
动态卡雷动态卡雷;
新的dynamicArray(&dynamicArray);
用户列表*用户列表;
newUserList(&userList);
开始(&dynamicArray,userList);
bubbleSort(&userList,(Comparator)lastNameComparator);
做{
printf(“欢迎!请选择一个选项\n”
“1-登录\n”
“2-新成员\n”
“3–退出\n”);
scanf(“%d”,选择(&C);
开关(选择){
案例1:
登录(&dynamicArray,&userList);
打破
案例2:
addNewMember(&dynamicArray,&userList);
打破
案例3:
结束(&dynamicArray,用户列表);
打破
违约:
printf(“选择错误,请重试\n”);
打破
}
}while(选项!=3);
返回0;
}
无效结束(DynamicArray*DynamicArray,UserList*UserList){
//文件*输出;
//output=fopen(“output.txt”,“w”);
//fclose(输出);
freeAllMemory(dynamicArray、userList);
}
void add(UserList*UserList,User*newUser){
UserItem*item=(UserItem*)malloc(sizeof(UserItem));
项目->数据=新用户;
item->next=NULL;
userList->last->next=项目;
userList->last=项目;
if(userList->head->data==NULL)
userList->head=userList->last;
}
无效登录(DynamicArray*DynamicArray,用户列表**用户列表){
用户*用户;
字符用户名[10],密码[15];
printf(“请输入您的用户名:\n”);
scanf(“%s”)