在C中将结构添加到动态数组中

时间:2018-02-28 18:33:15

标签: c

  

实现向动态数组添加新结构动物记录的函数add_record,并根据需要重新分配数组。动态数组的开始在参数array中给出,数组的当前长度在参数size中给出。要添加的新信息以参数newanimal给出。请注意,newanimal的内容需要复制到数组中。注意哪些参数是指针,哪些不是。   该函数在添加后将地址返回给动态数组。

这是我的任务,有人可以解释一下为什么我的函数add_record无效吗?此处的任何其他内容都无法更改,只有函数add_record可以更改。

我的代码:

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>


// Single animal entry
struct animal {
    char id[7]; // animal ID (6 characters) + terminating '\0'
    char *name; // animals name
    char *species; // animal species (string)
    unsigned char age; // animals age
    struct date entrydate;  // date of the animals arrival
};

struct animal *add_record(struct animal *array, unsigned int size, struct animal newanimal) 
{
    int n = size + 1;
    struct animal *newarray = realloc(array,  n*sizeof(struct animal));
    array = newarray; 

    strcpy(array->id, newanimal.id); //copying new id to array

    array->name = malloc(strlen(newanimal.name) + 1); //allocating memory for the string
    strcpy(array->name, newanimal.name);   //copying the new name to array

    array->species = malloc(strlen(newanimal.species) + 1); //allocating memory for the string
    strcpy(array->species, newanimal.species); //copying the new species to array

    array->age = newanimal.age;

    array->entrydate = newanimal.entrydate;

    return array;
}


int main()
{
    /*making new animal zoo which I want to which all of them I need to
      add to array in function add_record*/

    struct animal zoo[] = {
        { "123456", "Winnie-the-Pooh", "Bear", 94,{ 1,1,1924 } },
        { "555666", "Eeyore", "Donkey", 92,{ 1,1,1926 } },
        { "773466", "Piglet", "Very Small Animal", 30,{ 31, 12, 2015 } },
        { "234567", "Roo", "Kangaroo", 5,{ 31, 12, 2015 } }
    };

    struct animal *array = NULL;
    unsigned int len = 0;
    for (unsigned int i = 0; i < sizeof(zoo) / sizeof(struct animal); i++) {
        struct animal *newarray = add_record(array, len, zoo[i]);
        len++;
        array = newarray;
    }
    return 0;
}

2 个答案:

答案 0 :(得分:6)

array指向列表的第一个元素。当你这样做时:

array->age = newanimal.age;

您正在取消引用该指针,因此只更新列表的第一个元素。

由于你有一个指向数组开头的指针,你可以像数组一样索引它:

array[n-1].age = newanimal.age;

所以add_record中的任何地方都会指向成员解除引用,例如array->xxx将其更改为数组索引,并将成员访问权限更改为array[n-1].xxx

请注意,我们对索引使用n-1,因为大小为n的数组的索引从0n-1

答案 1 :(得分:5)

您已重新分配内存(假设N元素)。现在N-1元素将是旧元素,最后一个元素将是您将为此重新分配获得的额外元素。

所以据说,应该对最后一个元素进行更改。例如,您将复制到array[N-1].id,同样也会复制到其他成员。这样你就不会用新添加的元素覆盖第一个元素。 示例: -

strcpy(array[n-1].id, newanimal.id);

您还应该检查另一件事 - realloc的返回值 - 如果失败,它可能会返回NULL。检查它,如果它是非NULL,则只分配给指定的指针变量。同样的事情我要对malloc说 - 检查返回值。

我会像这样写realloc: -

struct animal *newarray = realloc(array,  n * sizeof *newarray);
if(!newarray){
   perror("realloc");
   exit(EXIT_FAILURE);
}
array = newarray;