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
1 Answer 1
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:
- There was not enough memory and
realloc()returnedNULL, which will go unnoticed because we didn't check the return value ofrealloc(). A subsequent operation would now be writing to / dereferencing / reading fromNULL, which would invoke undefined behaviour. - If
realloc()returnedNULL, 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. */
3 Comments
max_heap() not already allocated with malloc() or a similar function? The question said resizing. How was this insert function called? Kindly edit the question and provide a minimal reproducible example.insert() function could be declared to return a bool type instead of void, and return true on success, and false elsewise. The library user can then decide whether to exit the program or not. And consider accepting the answer if it you found the solution helpful.
realloc()to the original pointer. When (not if)realloc()fails, you overwrite the original pointer address withNULL, losing the address and creating a memory-leak. ALWAYSrealloc()using a temporary pointer, e.g.void *tmp = realloc (max_heap->heap, new_size);and validate therealloc()succeeds before assigning to the original pointer, e.g.if (!tmp) { perror ("realloc-max_heap->heap"); /* handle the error, e.g. return NULL */ };on success assignmax_heap->heap = tmp;. If you alloc in a function, it must have a return type to indicate success/failure.