C ++: remove an element from a dynamic array of struct and change other elements

I have an array of structures. I am trying to remove the list of elements from this array and shift the other elements to the left. After shifting the elements, I try to remove / free the memory at the end of the array, which we no longer need. I have the following code:

#include <iostream>
#include<stdio.h>
#include<stdlib.h>
void removeelement(int*);
void displayelements();

typedef struct {
   int n;
}element;
element** array;

int numofelements=5;

int main() {
   array = (element**)malloc(5*sizeof(element*));
   for(int i=0;i<5;i++){
       array[i] = new element;
       array[i]->n=i;
   }
   int removelist[3] = {1,3,4};
   removeelement(removelist);
   displayelements();
   return 0;
}
void removeelement(int* removelist){
    for(int i=0;i<3;i++){
        int index = removelist[i];
        int j;
        for(j=index;j<numofelements-2;j++){
            array[j] = array[j+1];
        }
        delete [] array[j+1];
        numofelements--;
    }
}
void displayelements(){
    int i=0;
    while(i<numofelements){
        printf("%d\n",array[i]->n);
        i++;
    }
}

But it delete [] array[j+1];raises an exception:

*** Error in `main': double free or corruption (fasttop): 0x0000000001861cb0 ***

I do not understand what causes this. As many people have suggested in other forums, I use the "new" operator to create a new dynamic element.

EDIT:

I made the following changes:

I changed for(j=index;j<numofelements-2;j++){tofor(j=index;j<numofelements-1;j++){

int index = removelist[i] before int index = removelist[i]-i

delete [] array[j+1] put delete array[numofelements+1] for. , , . :

#include <iostream>
#include<stdio.h>
#include<stdlib.h>
void removeelement(int*);
void displayelements();

typedef struct {
   int n;
}element;
element** array;

int numofelements=5;

int main() {
   array = (element**)malloc(5*sizeof(element*));
   for(int i=0;i<5;i++){
       array[i] = new element;
       array[i]->n=i;
   }
   int removelist[3] = {1,3,4};
   removeelement(removelist);
   displayelements();
   return 0;
}
void removeelement(int* removelist){
    for(int i=0;i<3;i++){
        int index = removelist[i]-i;
        int j=index;
        for(;j<numofelements-1;j++){
            array[j] = array[j+1];
        }
        numofelements--;
    }
    delete array[numofelements+1];
}
void displayelements(){
    int i=0;
    while(i<5){
        printf("%d\n",array[i]->n);
        i++;
    }
}

. std::vector, .

-2
3

, , removelist, , , .

array , ( ) , . , removelist .

. mayaknife user2079303, ( removelist). , std::vector , , .

, removelist ( ", ", , ):

void removeelement(int* removelist)
{
    for(int i = 2; i >= 0 ; --i)
    {
        int index = removelist[i];
        array* elementToDelete = array[index];
        for(j=index; j < numofelements -2; j++)
        {
            array[j] = array[j+1];
        }
        delete [] elementToDelete;
        numofelements--;
    }
}

, removelist - , . , , , removelist, , , removelist.


, malloc delete[]. undefined - /, ++.

, , :

#include <vector>
#include <algorithm>
#include <iostream>
#include <array>

struct element {
   int n;
};

int main() 
{
    std::vector<element> arr(5);

    for (int i = 0; i < 5; ++i)
       arr[i].n = i;

    std::array<int, 3> removelist = {1,3,4};
    // sort the list 
    std::sort(removelist.begin(), removelist.end());

    // work backwards, erasing each element
    std::for_each(removelist.rbegin(), removelist.rend(),[&](int n){arr.erase(arr.begin() + n);});

    // output results
    for( auto& v : arr)
       std::cout << v.n << '\n';
}

rbegin() rend(), removelist.

+1

delete[] , new[]. undefined.

, new, delete. delete[] .


, :

int numofelements=5;

//...
for(int i=0;i<3;i++){
    int index = removelist[i];
    int j;
    for(j=index;j<numofelements-2;j++){
        array[j] = array[j+1];
    }
    delete [] array[j+1];
    numofelements--;
}

array[4] . , removelist[i] == 1 , array[4] .

array[4] . , undefined.

, - array[j] = array[j+1] , , . : .

: , , 2 , numofelements 3. 4 0..2. , , ; , removelist[i] - i . - , .


, :

  • , array. , , , , .
  • malloc, . malloc.
  • RAII. , std::vector.
+3

:

delete [] array[j+1];

, 'array [j + 1]'. 'array [j + 1]' :

array[i] = new element;

, , . :

delete array[j+1];

, , , . , , , , "", "" , A, B, C, D E.

removeelements(), "array" :

array[0] -> A
array[1] -> B
array[2] -> C
array[3] -> D
array[4] -> E

'numofelements' 5.

removeelements() , , 1, :

for(j=1;j<3;j++){
    array[j] = array[j+1];
}

, [2] ' ' array [1] '' array [3] ', ' array [2]. "array" :

array[0] -> A
array[1] -> C
array[2] -> D
array[3] -> D
array[4] -> E

'j' 3, 'delete array [j + 1]' , 'array [4]', 'E'.

'numofelements' 4.

, , 3. "numofelements" 4, :

for(j=3;j<2;j++){
    array[j] = array[j+1];
}

'j' 3. , 2, , "array" .

'j' 3 ', delete [j + 1]' 'array [4]', E. , E , , .

, 3, , , 4. :

for(j=4;j<1;j++){
    array[j] = array[j+1];
}

'j' 4 . 'delete array [j + 1]' , 'array [5]', "array" .

As others have shown, the best way to handle this is to use std :: vector. However, the way to structure your code even std :: vector will not give you the desired results, because as soon as you remove one element from the "array", the indices of all subsequent ones will change, which means that the remaining indices in the 'removeelist' will no longer be correct .

I suggest that any changes you make, you manually execute the code, as I already above, tracking the contents of the array and the corresponding variables so that you can understand exactly what your code is doing.

+1
source

Source: https://habr.com/ru/post/1692610/


All Articles