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");
}
\\...
}
CodePudding user response:
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.