-1

Suppose, I have an array as follows:

arr[5]={1 2 3 4 3};

Now I want to search 3 and delete it. But in this array there two 3 are available. So, I want to delete both 3. How to do that?

biqarboy
  • 852
  • 6
  • 15
Minhaz
  • 1
  • 1
  • 1
    Arrays in C are fixed in size. So when you say "delete it" you're going to have to elaborate on what that means. What is your intended looks-like-this-after content of this fixed array? Just squishing the content and leaving the tail with whatever befalls it using two pointers (a reader and a writer) to walk the array is a common practice, but nonetheless, that array is five (apparently `int`) wide, and that's not going to change. Please [edit your question](https://stackoverflow.com/posts/66237008/edit) to provide additional details, ideally including what you've tried thus far. – WhozCraig Feb 17 '21 at 06:56
  • You cannot even delete one element – klutt Feb 17 '21 at 07:55

2 Answers2

0

Since you have a statically allocated array, it has a fixed size, and elements can't be deleted from it. So I'm going to assume you are talking figuratively, wanting a new array without those elements.


Approach one:

First, we need to find the size of the new array so we can allocate an array of the correct size.

size_t old_size = sizeof(arr)/sizeof(arr[0]);
size_t new_size = old_size;
for (size_t i=0; i<old_size; ++i) {
   if (arr[i] == to_remove) {
      --new_size;
   }
}

If new_size is zero, we should just set new_array to NULL and skip the rest.

Otherwise, we're now ready to allocate the new array.

int *new_array = malloc(sizeof(int) * new_size);
if (!new_array) {
   perror("malloc");
   exit(EXIT_FAILURE);
}

Finally, we can copy the selected elements.

for (size_t i=0, j=0; i<old_size; ++i) {
   if (arr[i] != to_remove) {
      new_array[j++] = arr[i];
   }
}

Alternatively, we can start by over-allocating.

int *new_array = malloc(sizeof(int) * new_size);
if (!new_array) {
   perror("malloc");
   exit(EXIT_FAILURE);
}

Then copy the selected elements.

size_t old_size = sizeof(arr)/sizeof(arr[0]);
for (size_t i=0, new_size=0; i<old_size; ++i) {
   if (arr[i] != to_remove) {
      new_array[new_size++] = arr[i];
   }
}

Then shrink the array size to what's required.

if (new_size) {
   int *temp = realloc(new_array, sizeof(int) * new_size);
   if (temp) {
      new_array = temp;
   }
} else {
   free(new_array);
   new_array = NULL;
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • @David Ranieri, No reason `realloc` should fail when *shrinking* the memory used. But let's say it is. The solution isn't to die, it's to keep using the larger-than necessary array. – ikegami Feb 17 '21 at 07:43
  • What do you mean? The correct wayto to call `realloc` is using an intermediate pointer: https://stackoverflow.com/questions/21006707/proper-usage-of-realloc , ah, ok, you mean there is no need to raise error and exit?, yes, but it was to mantian some coherence with your exit in `malloc` – David Ranieri Feb 17 '21 at 07:45
  • Re "*What do you mean?*", How can you run out of memory when *shrinking* the amount of memory used? Anyway, I did leave in the check, but I replaced your error handling with something sane. – ikegami Feb 17 '21 at 07:47
  • _How can you run out of memory when shrinking the amount of memory used?_ Thats a very good point @ikegami, but `realloc` can (in fact it does most of the times) get memory from other pages/blocks in an environment with another thread exhausting the memory, so it seems feasible. – David Ranieri Feb 17 '21 at 07:52
  • @David Ranieri, And thus, I left the check in. No need to make unwarranted assumptions – ikegami Feb 17 '21 at 07:53
0

@ikegami provides a solution returning a new allocated array, you can also work in place (memmove elements to the left) keeping count of how many elements the array has after deletion:

#include <stdio.h>
#include <string.h>

static size_t del(int *arr, size_t size, int elem)
{
    for (size_t i = 0; i < size;)
    {
        if (arr[i] == elem)
        {
            if (i < --size)
            {
                memmove(&arr[i], &arr[i + 1], (size - i) * sizeof(*arr));
            }
        }
        else
        {
            i++;
        }
    }
    return size;
}

int main(void)
{
    int arr[] = {1, 2, 3, 4, 3}; // do not hardcode the nr of elements
    size_t size = sizeof arr / sizeof *arr;

    for (size_t i = 0; i < size; i++)
    {
        printf("arr[%zu] = %d ", i, arr[i]);
    }
    printf("\nAfter deletion:\n");
    size = del(arr, size, 3);
    for (size_t i = 0; i < size; i++)
    {
        printf("arr[%zu] = %d ", i, arr[i]);
    }
    printf("\n");
    return 0;
}

Output:

arr[0] = 1 arr[1] = 2 arr[2] = 3 arr[3] = 4 arr[4] = 3 
After deletion:
arr[0] = 1 arr[1] = 2 arr[2] = 4 
David Ranieri
  • 39,972
  • 7
  • 52
  • 94