There are really two separate issues. The first is keeping the elements of the array in proper order so that there are no "holes" after removing an element. The second is actually resizing the array itself.
Arrays in C are allocated as a fixed number of contiguous elements. There is no way to actually remove the memory used by an individual element in the array, but the elements can be shifted to fill the hole made by removing an element. For example:
void remove_element(array_type *array, int index, int array_length)
{
int i;
for(i = index; i < array_length - 1; i++) array[i] = array[i + 1];
}
Statically allocated arrays can not be resized. Dynamically allocated arrays can be resized with realloc(). This will potentially move the entire array to another location in memory, so all pointers to the array or to its elements will have to be updated. For example:
remove_element(array, index, array_length); /* First shift the elements, then reallocate */
array_type *tmp = realloc(array, (array_length - 1) * sizeof(array_type) );
if (tmp == NULL && array_length > 1) {
/* No memory available */
exit(EXIT_FAILURE);
}
array_length = array_length - 1;
array = tmp;
realloc() will return a NULL pointer if the requested size is 0, or if there is an error. Otherwise, it returns a pointer to the reallocated array. The temporary pointer is used to detect errors when calling realloc() because instead of exiting, it is also possible to just leave the original array as it was. When realloc() fails to reallocate an array, it does not alter the original array.
Note that both of these operations will be fairly slow if the array is large or if a lot of elements are removed. There are other data structures like linked lists and hashes that can be used if efficient insertion and deletion is a priority.
Answer from Ben on Stack OverflowThere are really two separate issues. The first is keeping the elements of the array in proper order so that there are no "holes" after removing an element. The second is actually resizing the array itself.
Arrays in C are allocated as a fixed number of contiguous elements. There is no way to actually remove the memory used by an individual element in the array, but the elements can be shifted to fill the hole made by removing an element. For example:
void remove_element(array_type *array, int index, int array_length)
{
int i;
for(i = index; i < array_length - 1; i++) array[i] = array[i + 1];
}
Statically allocated arrays can not be resized. Dynamically allocated arrays can be resized with realloc(). This will potentially move the entire array to another location in memory, so all pointers to the array or to its elements will have to be updated. For example:
remove_element(array, index, array_length); /* First shift the elements, then reallocate */
array_type *tmp = realloc(array, (array_length - 1) * sizeof(array_type) );
if (tmp == NULL && array_length > 1) {
/* No memory available */
exit(EXIT_FAILURE);
}
array_length = array_length - 1;
array = tmp;
realloc() will return a NULL pointer if the requested size is 0, or if there is an error. Otherwise, it returns a pointer to the reallocated array. The temporary pointer is used to detect errors when calling realloc() because instead of exiting, it is also possible to just leave the original array as it was. When realloc() fails to reallocate an array, it does not alter the original array.
Note that both of these operations will be fairly slow if the array is large or if a lot of elements are removed. There are other data structures like linked lists and hashes that can be used if efficient insertion and deletion is a priority.
What solution you need depends on whether you want your array to retain its order, or not.
Generally, you never only have the array pointer, you also have a variable holding its current logical size, as well as a variable holding its allocated size. I'm also assuming that the removeIndex is within the bounds of the array. With that given, the removal is simple:
Order irrelevant
array[removeIndex] = array[--logicalSize];
That's it. You simply copy the last array element over the element that is to be removed, decrementing the logicalSize of the array in the process.
If removeIndex == logicalSize-1, i.e. the last element is to be removed, this degrades into a self-assignment of that last element, but that is not a problem.
Retaining order
memmove(array + removeIndex, array + removeIndex + 1, (--logicalSize - removeIndex)*sizeof(*array));
A bit more complex, because now we need to call memmove() to perform the shifting of elements, but still a one-liner. Again, this also updates the logicalSize of the array in the process.
Videos
Can't seem to find a way on how to do it....
for example if I have an array
a = {1,2,3}
and I want to delete a[1] so the result would be
a = {1,3 }
How can this be done ?
The contents of the array depends on where it's defined.
Global variables, or static local variables are zero-initialized. Local variables which are not static are not initialized, their values is indeterminate (and will seem random).
And there's no way to "delete" an element in an array, or make an element uninitialized. An array have a fixed size, that size can not be changed. And you can not reliably set an element to be indeterminate again (which is a state that you can not check for).
#include <stdio.h>
#define MAX_SIZE 100
int main()
{
int arr[MAX_SIZE];
int i, size, pos;
/* Input size and element in array */
printf("Enter size of the array : ");
scanf("%d", &size);
printf("Enter elements in array : ");
for(i=0; i<size; i++)
{
scanf("%d", &arr[i]);
}
/* Input element position to delete */
printf("Enter the element position to delete : ");
scanf("%d", &pos);
/* If delete position is invalid */
if(pos==size+1 || pos<0)
{
printf("Invalid position! Please enter position between 1 to %d", size);
}
else
{
/* Copy next element value to current element */
for(i=pos-1; i<size-1; i++)
{
arr[i] = arr[i + 1];
}
/* Decrement array size by 1 */
size--;
}
/* Print array after deletion */
printf("\nElements of array after delete are : ");
for(i=0; i<size; i++)
{
printf("%d\t", arr[i]);
}
return 0;
}