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.