I want to use realloc in C in an insert function for heap. This is the code:
typedef struct MaxHeap {
int size;
int* heap;
} MaxHeap;
void max_insert(MaxHeap* max_heap, int* key_index, int key) { // O(logn)
max_heap->heap = realloc((max_heap->size+1), sizeof * max_heap->heap);
max_heap[max_heap->size] = N_INF;
max_heap->size += 1;
increase_key(max_heap, key_index, max_heap->size, key)
}
And I get this warning:
warning: passing argument 1 of ‘realloc’ makes pointer from integer without a cast [-Wint-conversion]
and I tried this fix:
max_heap->heap = realloc((max_heap->heap), (max_heap->size+1) * sizeof(*(max_heap->heap)));
Update
I did this:
void max_insert(MaxHeap* max_heap, int* key_index, int key) { // O(logn)
int* temp = realloc (max_heap->heap, (max_heap->size + 1) * sizeof (*(max_heap->heap)));
if (!temp) exit(1);
max_heap->heap = temp;
max_heap->heap[max_heap->size] = N_INF;
max_heap->size += 1;
increase_key(max_heap, key_index, max_heap->size, key);
temp = 0;
}
And I got this error realloc(): invalid old size
You've swapped the arguments to realloc()
.
(max_heap->size+1)
evaluates to an int
, but the first argument to realloc()
expects a void *
pointer. Replace it with:
(max_heap->heap);
And the call to realloc()
becomes:
realloc (max_heap->heap, (max_heap->size + 1) * sizeof (*(max_heap->heap)));
Note that this fails for two reasons:
realloc()
returned NULL
, which will go unnoticed because we didn't check the return value of realloc()
. A subsequent operation would now be writing to / dereferencing / reading from NULL
, which would invoke undefined behaviour.realloc()
returned NULL
, we would lose access to the original memory, which would result in a memory leak.Fix:
Use a temporary pointer to hold the return value of realloc()
:
int *tmp = realloc (... , ...);
if (!tmp) {
perror ("realloc()");
/* realloc() was unable to allocate memory.
* The original memory is left untouched.
* Handle error here.
*/
}
/* Now we can assign the result to `max_heap->heap`: */
max_heap->heap = tmp;
tmp = 0; /* This is unnecessary, but eliminates a dangling pointer. */