为什么我会因CS50实验室的细分故障而遇到分割错误?

发布于 2025-02-07 02:17:06 字数 4756 浏览 1 评论 0原文

我在第56行上的分段故障

    // Simulate genetic inheritance of blood type

    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    // Each person has two parents and two alleles
    typedef struct person
    {
        struct person *parents[2];
        char alleles[2];
    }
    person;

    const int GENERATIONS = 3;
    const int INDENT_LENGTH = 4;

    person *create_family(int generations);
    void print_family(person *p, int generation);
    void free_family(person *p);
    char random_allele();

    int main(void)
    {
        // Seed random number generator
        srand(time(0));

        // Create a new family with three generations
        person *p = create_family(GENERATIONS);

        // Print family tree of blood types
        print_family(p, 0);

        // Free memory
        free_family(p);
    }

    // Create a new individual with `generations`
    person *create_family(int generations)
    {
        // TODO: Allocate memory for new person

        person *p = malloc(sizeof(person));

        if (p == NULL) {
            printf("Memory not allocated.\n");
            exit(0);
        }

        // If there are still generations left to create
        if (generations > 1)
        {
            // Create two new parents for current person by recursively calling create_family
            // TODO: Recursively create blood type histories for parents
            person *person0 = create_family(generations - 1);
            person *person1 = create_family(generations - 1);


            // TODO: Randomly assign current person's alleles based on the alleles of their parents
            p->alleles[0] = p->parents[0]->alleles[rand() % 2];
            p->alleles[1] = p->parents[1]->alleles[rand() % 2];

        }

       // If there are no generations left to create
        else
        {
            // TODO: Set parent pointers to NULL
            p->parents[0] = NULL;
            p->parents[1] = NULL;

            // TODO: Randomly assign alleles
            p->alleles[0] = random_allele();
            p->alleles[1] = random_allele();


        }

        // TODO: Return newly created person
        return NULL;
    }

    // Free `p` and all ancestors of `p`.
    void free_family(person *p)
    {
        // TODO: Handle base case
        if (p == NULL)
        {
            return;
        }

        // TODO: Free parents recursively
        if (p->parents[0] != NULL)
        {
            free_family(p->parents[0]);
            free_family(p->parents[1]);
        }


        // TODO: Free child
        free(p);

    }

    // Print each family member and their alleles.
    void print_family(person *p, int generation)
    {
        // Handle base case
        if (p == NULL)
        {
            return;
        }

        // Print indentation
        for (int i = 0; i < generation * INDENT_LENGTH; i++)
        {
            printf(" ");
        }

        // Print person
        if (generation == 0)
        {
            printf("Child (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]);
        }
        else if (generation == 1)
        {
            printf("Parent (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]);
        }
        else
        {
            for (int i = 0; i < generation - 2; i++)
            {
                printf("Great-");
            }
            printf("Grandparent (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]);
        }

        // Print parents of current generation
        print_family(p->parents[0], generation + 1);
        print_family(p->parents[1], generation + 1);
    }

    // Randomly chooses a blood type allele.
    char random_allele()
    {
        int r = rand() % 3;
        if (r == 0)
        {
            return 'A';
        }
        else if (r == 1)
        {
            return 'B';
        }
        else
        {
            return 'O';
        }
    }

。================

    Use of uninitialised value of size 8
    ==3017==    at 0x40126A: create_family (inheritance.c:61)
    ==3017==    by 0x401235: create_family (inheritance.c:56)
    ==3017==    by 0x4011B1: main (inheritance.c:30)
    ==3017==  Uninitialised value was created by a heap allocation
    ==3017==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==3017==    by 0x4011F4: create_family (inheritance.c:44)
    ==3017==    by 0x401235: create_family (inheritance.c:56)
    ==3017==    by 0x4011B1: main (inheritance.c:30)

I am getting a segmentation fault on line 56.

    // Simulate genetic inheritance of blood type

    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    // Each person has two parents and two alleles
    typedef struct person
    {
        struct person *parents[2];
        char alleles[2];
    }
    person;

    const int GENERATIONS = 3;
    const int INDENT_LENGTH = 4;

    person *create_family(int generations);
    void print_family(person *p, int generation);
    void free_family(person *p);
    char random_allele();

    int main(void)
    {
        // Seed random number generator
        srand(time(0));

        // Create a new family with three generations
        person *p = create_family(GENERATIONS);

        // Print family tree of blood types
        print_family(p, 0);

        // Free memory
        free_family(p);
    }

    // Create a new individual with `generations`
    person *create_family(int generations)
    {
        // TODO: Allocate memory for new person

        person *p = malloc(sizeof(person));

        if (p == NULL) {
            printf("Memory not allocated.\n");
            exit(0);
        }

        // If there are still generations left to create
        if (generations > 1)
        {
            // Create two new parents for current person by recursively calling create_family
            // TODO: Recursively create blood type histories for parents
            person *person0 = create_family(generations - 1);
            person *person1 = create_family(generations - 1);


            // TODO: Randomly assign current person's alleles based on the alleles of their parents
            p->alleles[0] = p->parents[0]->alleles[rand() % 2];
            p->alleles[1] = p->parents[1]->alleles[rand() % 2];

        }

       // If there are no generations left to create
        else
        {
            // TODO: Set parent pointers to NULL
            p->parents[0] = NULL;
            p->parents[1] = NULL;

            // TODO: Randomly assign alleles
            p->alleles[0] = random_allele();
            p->alleles[1] = random_allele();


        }

        // TODO: Return newly created person
        return NULL;
    }

    // Free `p` and all ancestors of `p`.
    void free_family(person *p)
    {
        // TODO: Handle base case
        if (p == NULL)
        {
            return;
        }

        // TODO: Free parents recursively
        if (p->parents[0] != NULL)
        {
            free_family(p->parents[0]);
            free_family(p->parents[1]);
        }


        // TODO: Free child
        free(p);

    }

    // Print each family member and their alleles.
    void print_family(person *p, int generation)
    {
        // Handle base case
        if (p == NULL)
        {
            return;
        }

        // Print indentation
        for (int i = 0; i < generation * INDENT_LENGTH; i++)
        {
            printf(" ");
        }

        // Print person
        if (generation == 0)
        {
            printf("Child (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]);
        }
        else if (generation == 1)
        {
            printf("Parent (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]);
        }
        else
        {
            for (int i = 0; i < generation - 2; i++)
            {
                printf("Great-");
            }
            printf("Grandparent (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]);
        }

        // Print parents of current generation
        print_family(p->parents[0], generation + 1);
        print_family(p->parents[1], generation + 1);
    }

    // Randomly chooses a blood type allele.
    char random_allele()
    {
        int r = rand() % 3;
        if (r == 0)
        {
            return 'A';
        }
        else if (r == 1)
        {
            return 'B';
        }
        else
        {
            return 'O';
        }
    }

===========

    Use of uninitialised value of size 8
    ==3017==    at 0x40126A: create_family (inheritance.c:61)
    ==3017==    by 0x401235: create_family (inheritance.c:56)
    ==3017==    by 0x4011B1: main (inheritance.c:30)
    ==3017==  Uninitialised value was created by a heap allocation
    ==3017==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==3017==    by 0x4011F4: create_family (inheritance.c:44)
    ==3017==    by 0x401235: create_family (inheritance.c:56)
    ==3017==    by 0x4011B1: main (inheritance.c:30)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

神妖 2025-02-14 02:17:06

为了扩展评论和以前的答案,我测试了您的代码。首先,如前所述,您需要返回指针“ P”而不是零值。此外,您想要产生父母和祖父母的两行代码需要从“*person0”和“*person1”的指针更改

person *person0 = create_family(generations - 1);
person *person1 = create_family(generations - 1);

p->parents[0] = create_family(generations - 1);
p->parents[1] = create_family(generations - 1);

不依赖孩子或孙子。通过这些修订,我能够得到一棵具有血型的简单家谱。

Child (Generation 0): blood type AB
Parent (Generation 1): blood type AO
    Grandparent (Generation 2): blood type OA
    Grandparent (Generation 2): blood type OB
Parent (Generation 1): blood type BB
    Grandparent (Generation 2): blood type BB
    Grandparent (Generation 2): blood type OB

希望能阐明事情。

问候。

To expand upon the comments and previous answers, I tested out your code. First off, as was noted, you need to return the pointer "p" instead of a NULL value. Also, the two lines of code where you are wanting to generate parents and grandparents need to be changed from

person *person0 = create_family(generations - 1);
person *person1 = create_family(generations - 1);

to

p->parents[0] = create_family(generations - 1);
p->parents[1] = create_family(generations - 1);

The pointers "*person0" and "*person1" appear to just be allocated structures that do not tie back to the child or grandchild. With those revisions, I was able to get a simple family tree with blood types.

Child (Generation 0): blood type AB
Parent (Generation 1): blood type AO
    Grandparent (Generation 2): blood type OA
    Grandparent (Generation 2): blood type OB
Parent (Generation 1): blood type BB
    Grandparent (Generation 2): blood type BB
    Grandparent (Generation 2): blood type OB

Hope that clarifies things.

Regards.

雅心素梦 2025-02-14 02:17:06

至少这个问题

未能返回分配的指针

    // return NULL;
    return p;

At least this problem

Failed to return allocated pointer

    // return NULL;
    return p;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文