0

Implement function add_record that adds a new struct animal record to the dynamic array, and reallocates the array as needed. The start of the dynamic array is given in parameter array, and the current length of the array is given in parameter size. The new information to be added is given as parameter newanimal. Note that the content of newanimal needs to be copied to the array. Pay attention to which parameters are pointers and which are not. The function returns address to the dynamic array after the addition.

That's my assignment here, can someone explain me why my function add_record is not working ? Anything else here cannot be changed, only the function add_record can be.

My code:

#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
  • Making changes to the first element always Commented Feb 28, 2018 at 18:35
  • Yea I thought about that but how can I manage the pointers to not make to changes to the first element always? @coderredoc Commented Feb 28, 2018 at 18:37

2 Answers 2

6

array points to the first element of the list. When you do this:

array->age = newanimal.age;

You're dereferencing that pointer and thus only updating the first element of the list.

Since you have a pointer to the start of an array, you can index it like an array:

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

So anyplace in add_record you do a pointer to member dereference like array->xxx change it to an array index and member accesss like array[n-1].xxx.

Note that we use n-1 for the index since an array of size n has indexes from 0 to n-1.

Sign up to request clarification or add additional context in comments.

3 Comments

or just use array[size], which is array[n-1] per the remedial math prior.
Got it now thanks for you but like if I write lets say "array[n-1].id" then what would be the same thing with arrow because "array[n-1]->id" is not working cause its pointer that way? @dbush
@michael The array index operator does an implicit pointer dereference. Specifically, array[i] is the same as *(array + i). Since array has type struct animal *, array[i] has type struct animal, so you can't use ->.
5

You have reallocated memory (suppose for N elements). Now for N-1 elements would be the old ones and the last one would be extra element that you will get for this reallocation.

So supposedly, the change should made to the last element. For example you would copy to array[N-1].id and same goes with other members also. That way you won't be overwriting the first element always with the newly added one. Example wise:-

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

There is also another thing that you should check - the return value of realloc - it might return NULL in case of failure. Check it and if it non-NULL then only assign to designated pointer variable. Same thing I would have to say for malloc - check the return value.

I would write realloc like this:-

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.