Reputation: 211
Here is the code in question, it's a function that reallocs a int array and adds a number to the end of it
int *add_to_array(int *arr, unsigned int num, int newval)
{
if(arr != NULL){
int *newarr = realloc(arr, sizeof(int) * (num+1));
if(!newarr){
free(arr);
}else{
free(newarr);
}
arr[num] = newval;
return arr;
}
else{
return NULL;
}
}
Problem is, when I call this function once, it works fine, but if I call it a second time, the debugger gives me a SIGABRT at the line
int *newarr = realloc(arr, sizeof(int) * (num+1));
Here is how I'm calling the function
array = add_to_array(array, 5, 10);
array = add_to_array(array, 6, 100);
EDIT: I managed to solve this with this new code
int *add_to_array(int *arr, unsigned int num, int newval)
{
if(arr != NULL){
int *newarr =realloc(arr, sizeof(int) * (num+1));
if(!newarr){
return NULL;
}else{
newarr[num] = newval;
return newarr;
}
}
else{
return NULL;
}
}
One more question, in the event whereby realloc fails to realloc the given pointer arr, does arr becomes null in that instance or is it still valid?
Upvotes: 1
Views: 2044
Reputation: 21965
Not only doesn't
else{
free(newarr);
}
make sense but also it defies the purpose of
int *newarr = realloc(arr, sizeof(int) * (num+1));
If realloc
is successful, do arr=newarr
.
Reference
[ realloc ] reference says:
On success, returns the pointer to the beginning of newly allocated memory. The returned pointer must be deallocated with free() or realloc(). The original pointer ptr is invalidated and any access to it is undefined behavior (even if reallocation was in-place).
On failure, returns a null pointer. The original pointer ptr remains valid and may need to be deallocated with free() or realloc().
Upvotes: 2
Reputation: 8464
If realloc fails you probably want to save the old array and do nothing, so:
if(!newarr){
free(arr);
Should be:
if(!newarr){
return NULL // Allocation fails, the old array saved. Check the return value outside the function
}
If realloc succeed, you sure don't want to free the new array, just update the last value in it, so:
}else{
free(newarr);
}
arr[num] = newval;
return arr;
Should be:
newarr[num] = newval;
return newarr;
Upvotes: 1
Reputation: 8209
Your code causes undefined behavior when you try to write to original block after reallocation. If reallocation fails - you free that block manually before writing, in other case you must not touch that block because realloc()
has returned new one and original one bay be freed internally. And SIGABRT - is an implementation-specific notification about detected heap corruption or misusing of malloc-family API. Read about realloc() carefully.
Upvotes: 1