Я пытаюсь создать связанный список пользователей в социальной сети в c.У меня есть 2 модуля:
Пользователь - структура, которая содержит имя пользователя (char), количество друзей (int) и связанный список друзей (каждый блок в списке содержит имяи указатель на следующего друга пользователя). Модуль пользователя имеет методы для добавления друга в список и его удаления.
2.Социальная сеть - общий модуль для организации пользователей.он содержит связанный список Users.The методы здесь контролируют пользователей.Он добавляет друзей как часть функции добавления отношений.он вызывает пользовательские методы и управляет пользователями как часть правил инкапсуляции.
Я использую malloc для структур и символов.В конце концов, я использую free для этих malloc в конце программы, используя такие функции, как Network_delete () и UserDelete (..). Я сталкиваюсь с ошибкой при вызове free в функции Network_delete () (точка останова без кода ошибки - даже не связанная с кучей)) и я не могу понять проблему.Я использую четко определенные правила использования malloc, но, возможно, я ошибаюсь в назначении.комментарий: def.h содержит перечисление Result, используемое в модулях.модули: User.h
#ifndef _USER_H_
#define _USER_H_
#include "defs.h"
typedef struct LINKED_LIST* L_list;
typedef struct user_t *PUser;
PUser User_Create(char* name);
void User_Delete(PUser pUser);
Result User_addFriend(PUser pUser, char* name);
Result User_removeFriend(PUser pUser, char* name);
char* User_getName(PUser pUser);
L_list User_getFriendsList(PUser pUser);
int User_getFriendsNum(PUser pUser);
#endif /* _USER_H_ */
User.c
#include "User.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// linked list
typedef struct LINKED_LIST {
char* name;
struct LINKED_LIST* pNext;
}L_L;
// user struct- include the user name,number of his friends and a list of his friends
typedef struct user_t
{
char* name;
L_list friends_list;
int friends_num;
}USER;
// user creator
PUser User_Create(char* name)
{
if (!name) return NULL;
PUser pUser;
pUser = (PUser)malloc(sizeof(USER));
if (pUser == NULL) return NULL;
if(!(pUser->name = (char*)malloc(1 +strlen(name)))) {
free(pUser);
return NULL;
}
pUser->friends_list = NULL;
pUser->friends_num = 0;
strcpy(pUser->name, name);
return pUser;
}
// user destructor-delete the user and his friends list
void User_Delete(PUser pUser)
{
if (!pUser) return;
L_list current = pUser->friends_list;
L_list to_delete = current;
while (current)
{
current = current->pNext;
free(to_delete->name);
free(to_delete);
}
pUser->friends_list = NULL;
free(pUser->name);
free(pUser);
}
//add new friend to the friends list
Result User_addFriend(PUser pUser, char* name)
{
if (!pUser||!name) return FAILURE;
L_list current = pUser->friends_list;
while (current)
{
if (strcmp(name, current->name)==0)
{
return FAILURE;
}
current = current->pNext;
}
L_list new_list_element = (L_list)malloc(sizeof(L_L));
if (!new_list_element) return FAILURE;
if (!(new_list_element->name = (char*)malloc(1 + strlen(name)))) {
free(new_list_element);
return FAILURE;
}
strcpy( new_list_element->name ,name);
new_list_element->pNext = pUser->friends_list;
pUser->friends_list = new_list_element;
pUser->friends_num++;
return SUCCESS;
}
//remove friends from the friends list
Result User_removeFriend(PUser pUser, char* name)
{
if (!pUser || !name) return FAILURE;
L_list current = pUser->friends_list;
L_list before_current = pUser->friends_list;
while (current)
{
if (strcmp(current->name, name) == 0)
{
before_current->pNext = current->pNext;
free(current->name);
free(current);
pUser->friends_num--;
return SUCCESS;
}
before_current = current;
current = current->pNext;
}
return FAILURE;
}
//get the user name
char* User_getName(PUser pUser)
{
if (!pUser) return NULL;
return pUser->name;
}
//get the first friend on the list
L_list User_getFriendsList(PUser pUser)
{
if (!pUser) return NULL;
return pUser->friends_list;
}
//get the user number of frinds
int User_getFriendsNum(PUser pUser)
{
if (!pUser) return 0;
return pUser->friends_num;
}
}
Socialnetwork.h
#ifndef _SOCIAL_NETWORK_H_
#define _SOCIAL_NETWORK_H_
#include "User.h"
typedef struct LINKED_LIST_SN* social_network_elem;// a list for social network
Result Network_addUser(char* member_invite, char* new_member);
Result Network_addRelationship(char* member1, char* member2);
Result Network_removeRelationship(char* member1, char* member2);
void Network_delete();
#endif /* _SOCIAL_NETWORK_H_ */
Socialnetwork.c
#include "SocialNetwork.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "User.h"
typedef struct LINKED_LIST_SN {
PUser pUser;
struct LINKED_LIST_SN* pNext;
}S_N_L;
social_network_elem pSocial_network;
//adding new user to the network
Result Network_addUser(char* member_invite, char* new_member)
{
if (!member_invite && !new_member) return FAILURE;//bad input
if (!new_member&&(pSocial_network!=NULL)) return FAILURE;
if (!member_invite&&new_member)//first member
{
pSocial_network = (social_network_elem)malloc(sizeof(S_N_L));
if (!pSocial_network) return FAILURE;
pSocial_network->pUser = User_Create(new_member);
pSocial_network->pNext = NULL;
return SUCCESS;
}
social_network_elem current = pSocial_network;
PUser pMember_invite=NULL;
while (current)
{
if (strcmp(new_member, User_getName(current->pUser)) == 0)//new_member already in social network
{
return FAILURE;
}
if (strcmp(member_invite, User_getName(current->pUser)) == 0)//apdating pointer to the member who invited
{
pMember_invite = current->pUser;
}
current = current->pNext;
}
if (!pMember_invite) return FAILURE; //no inviting member found in network
social_network_elem pNew_social_network_elem;
pNew_social_network_elem = (social_network_elem)malloc(sizeof(S_N_L));
if (!pNew_social_network_elem) return FAILURE;
pNew_social_network_elem->pUser = User_Create(new_member);
if (!pNew_social_network_elem->pUser) return FAILURE;
pNew_social_network_elem->pNext = pSocial_network;
pSocial_network = pNew_social_network_elem;
if (!Network_addRelationship(new_member, member_invite))
{
pNew_social_network_elem = pSocial_network;
pSocial_network = pSocial_network->pNext;
User_Delete(pNew_social_network_elem->pUser);
free(pNew_social_network_elem);
return FAILURE;
}
return SUCCESS;
}
Result Network_addRelationship(char* member1, char* member2)
{
if (!member1 || !member2) return FAILURE;
PUser pMember1 = NULL;
PUser pMember2 = NULL;
social_network_elem current = pSocial_network;
while (current)
{
if (strcmp(member1, User_getName(current->pUser)) == 0)//we found member 1
{
pMember1 = current->pUser;
}
if (strcmp(member2, User_getName(current->pUser)) == 0)//we found member 2
{
pMember2 = current->pUser;
}
current = current->pNext;
}
if (!pMember1 || !pMember2) return FAILURE;//one of the mambers not in the list
if (!User_addFriend(pMember1, member2)) return FAILURE;//create relationship failed
if (!User_addFriend(pMember2, member1))
{
User_removeFriend(pMember1, member2);
return FAILURE;
}
return SUCCESS;
}
Result Network_removeRelationship(char* member1, char* member2)
{
if (!member1 || !member2) return FAILURE;
PUser pMember1 = NULL;
PUser pMember2 = NULL;
social_network_elem current = pSocial_network;
while (current)
{
if (strcmp(member1, User_getName(current->pUser)) == 0)//we found member 1
{
pMember1 = current->pUser;
}
if (strcmp(member2, User_getName(current->pUser)) == 0)//we found member 2
{
pMember2 = current->pUser;
}
current = current->pNext;
}
if (!pMember1 || !pMember2) return FAILURE;//one of the mambers not in the list
if (User_getFriendsNum(pMember1) <= 1 || User_getFriendsNum(pMember2) <= 1) return FAILURE;//num of friends is less than 2
if (!User_removeFriend(pMember1, member2) || !User_removeFriend(pMember2, member1)) return FAILURE;//remove relationship failed
return SUCCESS;
}
void Network_delete()
{
social_network_elem current = pSocial_network;
social_network_elem tmp= NULL;
while (current)
{
tmp = current->pNext;
User_Delete(current->pUser);
free(current);
current = tmp;
}
}
У меня есть ошибки в вызове free в следующих функциях:
Network_delete ()
другие бесплатные вызовы не дают ошибок.
, кроме того, я использую Valgrind вUnix-среда для нарушения памяти и отладки, и похоже, что malloc создают блоки разных размеров по сравнению с типами, которые в ней содержатся.