Reputation: 7
I have an array that I want to increase the size of during runtime. I assign values to the elements of the array by using a loop, and when the index of the loop hits the number of elements of the array, I want to increase the size of the array.
What I did, actually works; I can assign values to elements of the array that I would normally not be able to assign any values to without increasing the array's size. The bad side is, it gives me a crash after the program runs and finishes smoothly. What is wrong here? Is it that maybe the memory that I try to allocate for the array is already filled?
int main()
{
int arr[3];
int num_of_elements = sizeof(arr)/sizeof(arr[0]); // This gives '3', I checked
for(i = 0; i < 10; i++)
{
if(i == num_of_elements)
{
num_of_elements = num_of_elements + 10;
realloc(arr, num_of_elements);
}
arr[i] = i+10;
printf("%d\n", arr[i]);
}
return 0;
}
Upvotes: 1
Views: 346
Reputation: 30906
Well you are invoking undefined behavior. From standard §7.22.3.5
void *realloc(void *ptr, size_t size);
If ptr is a null pointer, the realloc function behaves like the
malloc
function for the specified size. Otherwise, ifptr
does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to the free orrealloc
function, the behavior is undefined. If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.
By memory management function - it means malloc
etc. arr
is not dynamically allocated memory. So passing this to realloc
is undefined behavior - in your case that behavior leads you to crash in program.
It would work if you do this
int *arr = malloc(sizeof(int)*3);
if( arr == NULL){
perror("Malloc failed");
exit(EXIT_FAILURE);
}
...
int *p = realloc(arr,num_of_elements*sizeof(int));
^^^^^
if(p == NULL ){
perror("realloc failed");
exit(EXIT_FAILURE);
}
arr = p;
Check how realloc
is used.
The takeaways will be:-
realloc
, malloc
. 10*sizeof(int)
amount of memory.arr = realloc(arr,SIZE)
in case realloc
fails you will have memory leak.realloc
to p
after all you do arr=p
annyway?Two reasons so far
The answer to this is when realloc
fails then it returns NULL
now if you assign arr
to NULL
then you may have a situation where you lose the only reference to the previously allocated memory - leading to a memory leak. That's why we do it like this.
Note this from standard
The
realloc
function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.
Notice that may
part - it might be the same address as before as pointed by arr
or it might be different one. That explains why we should store it in some temporary pointer and then we assign it later.
Upvotes: 5
Reputation: 37217
You should have done this:
arr = realloc(arr, num_of_elements);
^^^^^
realloc()
does not necessarily extend or shrink the allocated memory in-place, it invalidates the dynamic memory that its first argument points to and allocates new memory, while preserving the content of the previous memory.
One possible implementation is :
void* realloc(void* ptr, size_t size) {
void* ret = malloc(size);
if (ret == NULL) return ret;
if (ptr != NULL) {
memcpy(ret, ptr, /* previous size from system */);
free(ptr);
}
return ret;
}
Upvotes: 1