我的变量在移至下一个函数后发生了变化

我的作业有一个似乎无法解决的问题,即在功能“ add_new_family”中成功添加家庭并移至“ add_new_child”后,创建一个用于处理城市家庭信息的工具的任务。与调试器一起工作时,我注意到仅通过移至函数的第一行或第二行,我的原始结构变量就随机更改,paretns名称变为垃圾,如果我继续使用该函数并实际上尝试添加另一个子代, ,它会将信息保存在父母的姓名上,因此,我似乎无法找出造成此问题的原因。

请原谅我的内存分配转换,如果它困扰着任何人,我之前在stackoverflow中读过,也许没有必要,但我的教授坚持认为。

There might be other crucial problems with my code, im a first year student, although it would be appreciated if you note it, but my main focus is just figuring out the cause of those random changes after I send my struct to the "add_new_child" function, I add an image of before and after to make clear of whats happening picture

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#define SIZE 10000;

typedef struct person {
    char* name;
    int gender;//1-female, 0-male
}Person;

typedef struct {
    char* family_name;
    Person* mother, *father; // parents' names
    Person* *children_list;// list of the children in this family
    unsigned child_list_size; // size of child_list array
    unsigned current_listChild_size;
}Family;

typedef struct {
    Family** list;
    unsigned current_listFamily_size; // current size of family
}ListFamilys;

ListFamilys* new_city(ListFamilys* s);
void add_new_family(ListFamilys* s, char* fname);
void add_new_child(ListFamilys* s, char* surname);

void main()
{
    ListFamilys* list = (ListFamilys*)malloc(1 * sizeof(ListFamilys));
    assert(list);
    list = new_city(list);
    add_new_family(list, "james");

    add_new_child(list, "james");
    system("pause");
}


ListFamilys* new_city(ListFamilys* s)
{

    assert(s->list = (Family**)calloc(1, sizeof(Family*)));
    s->current_listFamily_size = 0;
    return s;
}

void add_new_family(ListFamilys* s, char* fname)
{
    unsigned int size = SIZE;
    if (s->current_listFamily_size >= size)
    {
        printf("\nAccording to our database, it will not be possible to add another family in Angola, as the city reached its capacity");
        return;
    }

    for (unsigned int i = 0; i < s->current_listFamily_size; i++)
    {
        if (strcmp(s->list[i]->family_name, fname) == 0)
        {
            printf("\nERROR 1: A family with the surname of %s already exist in the database", fname);
            return;
        }
    }

    s->current_listFamily_size += 1;
    /*assert(s = (ListFamilys*)realloc(s, s->current_listFamily_size * sizeof(ListFamilys)));
    assert(s->list = (Family**)calloc(1 , sizeof(Family*)));*/
    assert(s->list[s->current_listFamily_size - 1] = (Family*)calloc(1, sizeof(Family)));
    assert(s->list[s->current_listFamily_size - 1]->father = (Person*)malloc(1 * sizeof(Person)));
    assert(s->list[s->current_listFamily_size - 1]->mother = (Person*)calloc(1, sizeof(Person)));
    int numOfParents = 0;

    printf("Creating new data for the [%s] family, please provide the number of parents (1/2): ", fname);
    scanf("%d", &numOfParents);

    s->list[s->current_listFamily_size - 1]->family_name = fname;

    char tmpname[100];
    char tmpname1[100];
    int tmpgender = 0;
    int tmpgender1 = 0;
    switch (numOfParents)
    {
       case 0:
        printf("\nERROR 2: A newly created family cannot contain no parents at all or more than 2 parents, please try again.");
        return;

       case 1:
        printf("\nPlease provide the name of the parent No.1: ");
        scanf("%s", tmpname);
        printf("\nPlease provide the gender of parent No.1 [1 for female / 0 for male]: ");
        scanf("%d", &tmpgender);
        if (tmpgender == 0)
        {
            s->list[s->current_listFamily_size - 1]->father->gender = tmpgender;
            s->list[s->current_listFamily_size - 1]->father->name = tmpname;
            s->list[s->current_listFamily_size - 1]->mother = NULL;
        }
        else
        {
            s->list[s->current_listFamily_size - 1]->mother->gender = tmpgender;
            s->list[s->current_listFamily_size - 1]->mother->name = tmpname;
            s->list[s->current_listFamily_size - 1]->father = NULL;
        }
        break;

       case 2:
        printf("\nPlease provide the name of the parent No.1:");
        scanf(" %s", tmpname);
        printf("\nPlease provide the gender of parent No.1 [1 for female / 0 for male]: ");
        scanf("%d", &tmpgender); 
        printf("\nPlease provide the name of the parent No.2:");
        scanf(" %s", tmpname1);
        printf("\nPlease provide the gender of parent No.2 [1 for female / 0 for male]: ");
        scanf("%d", &tmpgender1);
        if (tmpgender == 0)
        {
            s->list[s->current_listFamily_size - 1]->father->gender = tmpgender;
            s->list[s->current_listFamily_size - 1]->father->name = tmpname;
            s->list[s->current_listFamily_size - 1]->mother->gender = tmpgender1;
            s->list[s->current_listFamily_size - 1]->mother->name = tmpname1;
        }
        else
        {
            s->list[s->current_listFamily_size - 1]->mother->gender = tmpgender;
            s->list[s->current_listFamily_size - 1]->mother->name = tmpname;
            s->list[s->current_listFamily_size - 1]->father->gender = tmpgender1;
            s->list[s->current_listFamily_size - 1]->father->name = tmpname1;
        }
        break;
       default:
        printf("\nERROR 2: A newly created family cannot contain no parents at all or more than 2 parents, please try again.");
        return;

    }

    int numOfChildren = 0;
    printf("\nPlease provide the number of children in the [%s] family: ", fname);
    scanf("%d", &numOfChildren);

    if (numOfChildren == 0)
    {
        s->list[s->current_listFamily_size - 1]->children_list = NULL;
        s->list[s->current_listFamily_size - 1]->child_list_size = 0;
        s->list[s->current_listFamily_size - 1]->current_listChild_size = 0;
    }
    else
    {
        assert(s->list[s->current_listFamily_size - 1]->children_list = (Person**)malloc((numOfChildren + 2) * sizeof(Person*)));
        s->list[s->current_listFamily_size - 1]->child_list_size = numOfChildren + 2;
        for (int i = 0; i < numOfChildren; i++)
        {
            char tmpname2[100];
            tmpgender = 0;
            printf("\nPlease provide the name of the child No.%d:", i+1);
            scanf(" %s", tmpname2);
            printf("\nPlease provide the gender of child No.%d [1 for female / 0 for male]: ", i+1);
            scanf("%d", &tmpgender);
            assert(s->list[s->current_listFamily_size - 1]->children_list[i] = (Person*)malloc(1 * sizeof(Person)));
            s->list[s->current_listFamily_size - 1]->children_list[i]->gender = tmpgender;
            s->list[s->current_listFamily_size - 1]->children_list[i]->name = tmpname2;
        }
        for (int i = 0; i < 2; i++)
        {
            s->list[s->current_listFamily_size - 1]->children_list[numOfChildren + i] = NULL;
        }

        s->list[s->current_listFamily_size - 1]->current_listChild_size = numOfChildren;
    }

    printf("\nFamily was added to the database SUCCESSFULY.");
    return;
}

void add_new_child(ListFamilys* s, char* surname)
{
    int truth = 0;
    unsigned int index = 0;
    for (unsigned int i = 0; i < s->current_listFamily_size; i++)
    {
        if (strcmp(s->list[i]->family_name , surname) == 0)
        {
            index = i;
            truth = 1;
        }
    }

    if (truth == 0)
    {
        printf("\nERROR 3: Family wasnt found in the database, try again");
        return;
    }

    char tmpname4[100];
    int gender = 0;

    if (s->list[index]->current_listChild_size < s->list[index]->child_list_size)
    {
        printf("\nPlease provide the name of the child: ");
        scanf(" %s", tmpname4);
        printf("\nPlease provide the gender of child [1 for female / 0 for male]: ");
        scanf("%d", &gender);
        assert(s->list[index]->children_list[s->list[index]->current_listChild_size] = (Person*)malloc(1 * sizeof(Person)));
        s->list[index]->children_list[s->list[index]->current_listChild_size]->gender = gender;
        s->list[index]->children_list[s->list[index]->current_listChild_size]->name = tmpname4;
    }
    else
    {
        s->list[index]->child_list_size += 1;
        s->list[index]->current_listChild_size += 1;
        assert(s->list[index]->children_list = (Person**)malloc(1 * sizeof(Person*)));
        printf("\nPlease provide the name of the child: ");
        scanf(" %s", tmpname4);
        printf("\nPlease provide the gender of child [1 for female / 0 for male]: ");
        scanf("%d", &gender);
        s->list[index]->children_list[s->list[index]->current_listChild_size] = (Person*)malloc(1 * sizeof(Person));
        s->list[index]->children_list[s->list[index]->current_listChild_size]->gender = gender;
        s->list[index]->children_list[s->list[index]->current_listChild_size]->name = tmpname4;
    }

    printf("\nChildren information was updated SUCCESSFULY");
    return;
}
评论
  • 客官,不要
    客官,不要 回复

    You're setting the name member to a pointer to a local variable, which becomes invalid when the function returns. You need to make a dynamic copy of the string.

                s->list[s->current_listFamily_size - 1]->father->name = strdup(tmpname);
    

    姓,母亲的名字和所有孩子的名字都一样。