Home > Net >  How can I return the array after deleting an element?
How can I return the array after deleting an element?

Time:10-26

The following function

int* del(int* array, int el)

is receiving a dinamically allocated array. What could I write inside of it in order to delete the element and also to return the array obtained?

CodePudding user response:

This is not a good idea, but it's answering the question:

#include <algorithm> // std::copy_n
#include <iostream>

int* del_element(int* vector, int dim, int el) {
    int* rv = nullptr;
    if(--dim > 0) {            // must have at least 1 element
        rv = new int[dim];     // allocate new memory

        // copy the the elements before `el`:
        std::copy_n(vector, el, rv);
    
        // copy the elements after `el`:
        std::copy_n(vector   el   1, dim - el, rv   el); 
    }
    delete[] vector; // delete the old data
    return rv;       // return the new data (nullptr if empty)
}

int main() {
    int* v = new int[10]{0,1,2,3,4,5,6,7,8,9};
    
    v = del_element(v, 10, 5); // erase the sixth element

    for(int* it = v, *end = v   9; it != end;   it) {
        std::cout << *it << '\n';
    }

    delete[] v;
}

Without allocating new memory, you could just std::move the data to erase the selected element:

int* del_element(int* vector, int dim, int el) {
    
    // move the elements after `el` one step to "the left":
    std::move(vector   el   1, vector   dim, vector   el);
    
    return vector;
}

A better approach would be to use a std::vector<int>:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v{0,1,2,3,4,5,6,7,8,9};
    
    v.erase(v.begin()   5); // erase the sixth element
    
    for(int value : v) {
        std::cout << value << '\n';
    }
}

CodePudding user response:

This is a bad idea (or maybe a bad school exercise). Please use a std::vector or, in the worst case, a std::array.

(Also, maybe do not call a plain array a “vector”, do not call size a dim (which may be confused with the number of dimensions), do not use an int were size_t should be, avoid raw pointers when possible etc.)

The function should be returning a std::unique_ptr<int[]> to clearly document the ownership transfer.

If you are supposed to dispose of the original array, take a std::unique_ptr<int[]> argument. If you are not supposed to dispose of the original array, take a const int * argument.

The most importantly, double-check everything with valgrind; it must terminate error-free.

Last but not least, if possible, do not limit your element type to int; your future self will thank you.

#include <memory>

template<typename Element>
std::unique_ptr<Element[]> del_element(std::unique_ptr<Element[]> array,
                                       size_t size, size_t idx) {
  auto result = std::make_unique<Element[]>(size - 1);
  for (size_t i = 0; i < idx;   i) result[i] = array[i];
  for (size_t i = idx   1; i < size;   i) result[i - 1] = array[i];
  return result;
}

Also, set up a printing function for debugging.

#include <iostream>

template<typename Element>
void print_array(const Element *array, size_t size) {
  std::cout << '[';
  if (size) {
    std::cout << *array;
    for (size_t i = 1; i < size;   i) std::cout << ", " << array[i];
  }
  std::cout << ']' << std::endl;
}

Also, don’t forget to test it. valgrind is your friend!

int main() {
  std::unique_ptr<int[]> first = std::make_unique<int[]>(7);
  for (size_t i = 0; i < 7;   i) first[i] = i - 3;
  print_array(first.get(), 7);
  std::unique_ptr<int[]> second = del_element(std::move(first), 7, 3);
  print_array(second.get(), 6);
  std::unique_ptr<int[]> third = del_element(std::move(second), 6, 0);
  print_array(third.get(), 5);
  std::unique_ptr<int[]> forth = del_element(std::move(third), 5, 4);
  print_array(forth.get(), 4);
  std::unique_ptr<int[]> fifth = del_element(std::move(forth), 4, 2);
  print_array(fifth.get(), 3);
  std::unique_ptr<int[]> sixth = del_element(std::move(fifth), 3, 1);
  print_array(sixth.get(), 2);
  std::unique_ptr<int[]> seventh = del_element(std::move(sixth), 2, 0);
  print_array(seventh.get(), 1);
  std::unique_ptr<int[]> eighth = del_element(std::move(sixth), 1, 0);
  print_array(eighth.get(), 0);
}

Last but not least, please throw all this nonsense away and use a std::vector, std::deque, std::list or whatever fits your use case. It has more features and fewer bugs.

  • Related