Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Points returned by memory allocation functions

I am learning C from the book by K.N.King and am going through the programming projects for chapter 17. I came across a self inflicted bug while I was completing the first project. It was undefined behaviour of the program since I was passing realloc() a copy of a pointer returned from an earlier malloc() call, since the realloc() call was occurring in a function other than main(). After re-reading parts of the chapter I realised that realloc() has undefined behaviour in this case.

I have tried to search why this is the case to no avail. So does anyone here know why the pointer passed to realloc() must be a pointer returned from an earlier call of malloc(), calloc() or realloc() and not a copy of these? Also, aren’t we inherently always making a copy of a pointer returned by realloc() whenever we want to resize a memory block?

int num_parts = 0, max_parts = 10;

int main(void)
{
    struct part *inventory = malloc(max_parts * sizeof(*inventory));
    \\...
    switch(ch) {
        \\...
        case 'i':
            insert(inventory, &num_parts, &max_parts);
            break;
        \\...
    }
}

void insert(struct part *inventory, int *num_parts, *max_parts)
{
    if (*num_parts == *max_parts) {
        *max_parts += 10;
        struct part *temp = realloc(inventory, max_parts * sizeof(*temp));
        if (temp != NULL)
            inventory = temp;
        else
            printf("Error:...\n");
    }
    \\...
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The function insert accepts the pointer inventory by value

void insert(struct *inventory, int *num_parts, *max_parts)

and

insert(inventory, &num_parts, &max_parts);

It means that the function deals with a copy of the the value of the original pointer. Changing the copy within the function like

    if (temp != NULL)
        *inventory = temp;

does not influence on the value of the original pointer declared in main.

You need to pass the pointer by reference through a pointer to it.

That is

insert( &inventory, &num_parts, &max_parts);

And the function will look like

void insert(struct **inventory, int *num_parts, *max_parts)
{
    if (*num_parts == *max_parts) {
        *max_parts += 10;
        struct part *temp = realloc( *inventory, max_parts * sizeof(*temp));
        if (temp != NULL)
            *inventory = temp;
        else
            printf("Error:...\n");
    }
    \\...
}

In this case dereferencing the function parameter struct **inventory within the function we can get a direct access to the original pointer (object) and thus can change it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading