Problem with pointer deallocation in chained list

2

I have a problem with the deallocation of pointers in my code a few days ago. I try to make sure that the point of my on-screen object is greater than one value, move this object out of memory, but for some reason this is not working and is giving an error that hangs everything up.

Finally, I think I'm doing something very wrong, but I could not identify what it is, follow the code:

This is the structure I'm using for creating the list

//estruturas
//asteroide
struct Asteroides {
    int x;
    int y;
    int vel;
    ALLEGRO_BITMAP *Img;
    int id;
    char palavra;
};
//um tipo de variavel lista que eh um ponteiro
typedef struct elemento* Lista;
//define elemento
struct elemento {
    struct Asteroides dados;
    struct elemento *Prox;
};
//define um tipo de elemento auxiliar
typedef struct elemento Elem;

This is the allocation of the elements in the list:

//insere na lista
void ins_list(int num, Lista* li){
    srand(time(NULL));
    for(int i = 0; i < num; i++){
        Elem* no = (Elem*) malloc(sizeof(Elem));
        if(no == NULL) break;
        no->dados.Img = Asteroide;
        no->dados.x = (rand()%1000);
        no->dados.y = -200;
        no->dados.id = i;
        while(no->dados.vel <= 0 || no->dados.vel >5){
            no->dados.vel = (rand()%10);
        }
        no->Prox = (*li);
        *li = no;
    }
}

This is the part that I try to unsuccessfully remove, the removal code is along with the image refresh:

//anima asteroides
void anima(Lista* li, int frame, int agFramex, int agFramey){
    Elem* no = (Elem*) malloc(sizeof(Elem));
    Elem* ant = (Elem*) malloc(sizeof(Elem));
    no = (*li);
    ant = no;
    while(no != NULL){
        al_draw_bitmap_region(no->dados.Img, agFramex*frame, agFramey*frame, frame, frame, no->dados.x, no->dados.y, 0);
        if(no->dados.y > ALT+200){
            ant->Prox = no->Prox;
            free(no);
            no = ant->Prox;
        }
        no->dados.y += no->dados.vel;
        ant = no;
        no = no->Prox;
    }
}

If if is the removal code:

if(no->dados.y > ALT+200){
   ant->Prox = no->Prox;
   free(no);
   no = ant->Prox;
 }

I get segmentation fault 11 which is actually allocation error, can anyone help me? Thank you.

Obs: The error occurs when the first object reaches the condition.

    
asked by anonymous 02.10.2015 / 22:28

2 answers

0

A problem there (I can not guarantee that it is the only one) is that when there is an item removal, you advance to the next two times: one when doing the removal and the other at the end of the while.

If% with removed% is last in the list, no (and therefore ant->Prox ) will point to no , and soon after null you if that should be the cause of your segmentation fault.

One solution is to perform the upgrade and upgrade from not only if the no is not removed:

while(no != NULL){
        al_draw_bitmap_region(no->dados.Img, agFramex*frame, agFramey*frame, frame, frame, no->dados.x, no->dados.y, 0);
        if(no->dados.y > ALT+200){
            ant->Prox = no->Prox;
            free(no);
            no = ant->Prox;
            continue;
        }
        no->dados.y += no->dados.vel;
        ant = no;
        no = no->Prox;
    }

(The insertion of the 'continue' command above passes the program flow immediately to the test of no->dados.y += no->dados.vel; which is the right thing to do there: while is already pointing to what was previously no .

    
03.10.2015 / 01:53
0

It is not a solution, but a suggestion.

Why do you spend so much time using linked lists if you can use Arrays?

When you are learning you can not forget the basics. In my view threaded lists for a game does not make sense.

My suggestion would be to use the structure Asteroide a bool that contains whether the asteroid is alive or not. Then with Arrays I just drew and refreshed the living.

    
03.10.2015 / 15:57