当我在我的项目上运行valgrind时,没有释放5个分配中的4个,我也无法理解为什么。
我尝试取消引用并释放似乎有问题的变量。
#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);
}
}
我看不到我找到泄漏的原因,它是由什么引起的,valgrind显示在newDynamicArray函数和newUserList中仍有72个字节可以访问。
答案 0 :(得分:1)
我还有72个字节可以访问
这些字节不是内存泄漏,例如通过 main
中的变量 dynamicArray 仍然可以访问Valgrind明确表示何时是内存泄漏