# Deleting an element from an array

• 11-18-2003
Matt13
Deleting an element from an array
Does anyone know a more elegant way than this of deleting a given element from an array:

Code:

```void deletefrom(int[], int, int); int main(void) {     /*stuff*/   int bob, size_of_frank;   int *frank;   frank=(int*)calloc(size_of_frank,sizeof(int));   /*call for element "bob" to be deleted from array "frank"*/   deletefrom(frank,bob,size_of_frank);   /*etc*/   return 0; } void deletefrom(int frank[], int bob, int size_of_frank) {   int i, j=0, *temp;   temp=(int*)calloc(size_of_frank-1,sizeof(int));   for(i=0; i<size_of_frank, i++){       if(frank[i]==bob)         continue;              /*Or should this be break?*/       else{         temp[j]=frank[i];         j++       }   }   free(frank);   frank=(int*)calloc(size_of_frank-1,sizeof(int));   for(i=0;i<size_of_frank-1;i++)       frank[i]=temp[i];   return; }```
But something about this gives me the creeps and that is "Once I have free'd frank, is he gone from main forever? Can main see the new frank?"

Help is much appreciated, even if it turns out to be the thread where you explained this to someone else last week (I did look! But I couldn't find anything on the first five pages...)

Matt
• 11-18-2003
jim mcnamara
deletefrom() should call reallocate(), not calloc.
You can do all of deletefrom() something like this:

Code:

```void deletefrom(int frank[], int bob, int size_of_frank) {   /* this truncates the array at the value just before bob */   int i=0,       found=0;   for(i=0; i<size_of_frank; i++){       if(frank[i]==bob){         found=i+1;         break;                  }   }   if (found)           reallocate(frank,sizeof(int)*found);   return; }```
• 11-18-2003
Matt13
1) Do you mean realloc?

2) How does that work? I mean, if you use realloc to remove an element from an array, which one does it delete?

Matt
• 11-18-2003
jim mcnamara
Yes I do mean realloc - we have our own fornt-ends for memory management - and reallocate is the wrapper for realloc()

• 11-18-2003
thefroggy
@ jim:
Your code will actually delete everything after "bob" in the array.

@ matt:
When your program reallocates "frank", the frank pointer in main is left pointing at the previous allocated memory. You'll need to pass a pointer to a pointer if you want to change the passed in value. Also, if "bob" is not found in your array, you just end up chopping off the last element.

As for elegance, you might be able to write a few less lines if you look into memmove(). With that and realloc(), you could probably cut that function in half, and it would be somewhat cleaner.
• 11-18-2003
Codeplug
This is fairly elegant, in my opinion :)
Code:

```#include <stdio.h> #include <stdlib.h> #include <string.h> void print_data(const int *data, size_t len) {     size_t n = 0;     printf("len = %d, data = ", len);     for (; n < len; n++)         printf("%d,", data[n]);     printf("\n"); }//print_data void remove_data(int key, int *data, size_t *plen) {     int *data_end = data + *plen;     while (data < data_end)     {         if (*data == key)         {             (*plen)--;             data_end--;             memmove(data, data + 1, (int)data_end - (int)data);             continue;         }//if         data++;     }//while }//remove_data int main() {     int data[] = {0,0,1,2,0,3,4,0,5,6,7,0,8,9,0,};     size_t data_sz = sizeof(data)/sizeof(data[0]);     print_data(data, data_sz);     remove_data(0, data, &data_sz);     print_data(data, data_sz);     return 0; }//main```
gg
• 11-18-2003
Sebastiani
You guys are making this too complicated.

First off, the function should *not* delete memory from some other part of the program. It's just not a good practice. Functions should be 'well-behaved' and perform clear-cut operations.

Also, remember that arrays have two measures to keep track of. The size is the capacity and the length is the amount currently in use. Allocation functions worry about size and data manipulation functions about length.

To remove a given value from an array is simply:

Code:

```int  remove(int array[], int * length, int value) {  int x = 0;   for(int index = 0; index < *length; ++index)      if(array[index] != value)        array[x++] = array[index];  return *length = x; }```

We know that 'x' will always be less than or equal to 'index', that's why it's safe to use the array itself to all the work.
• 11-19-2003
Matt13
@Seb: This not chopping up memory outside of main is probably what has been giving the creeps - because it seems like bad practice intuitively... but I'm not entirely sure what your code is doing so I'll have to work it out...