Функция free () в c на структуре генерирует точку останова без кода ошибки - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь создать связанный список пользователей в социальной сети в c.У меня есть 2 модуля:

  1. Пользователь - структура, которая содержит имя пользователя (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 создают блоки разных размеров по сравнению с типами, которые в ней содержатся.

...