Problem with threaded list pointer offset

Asked

Viewed 208 times

2

I’ve had a problem with the shift of pointers in my code for a few days now. I try to make that if the point of my object on the screen is greater than a value, offset this object from memory, but for some reason this is not working and is giving an error that hangs everything.

Anyway, I believe I’m doing something very wrong, but I couldn’t identify what it is, follow the code:

This is the structure I’m using for the list creation

//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 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 I try to remove without success, the removal code is along with the image update:

//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 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 in fact is allocation error, can anyone help me? Thank you.

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

  • It’s been a while since I’ve done anything in c and barely remember the pointer syntax so maybe it’s not that, but I believe it’s because when the first object is removed and its memory is released, the pointer in its main code that points to the beginning of its list, keep pointing to that object already released. I imagine you should pass a reference to the memory position of that pointer and if it is the first object to be removed, the list start pointer should be updated

  • Dude I don’t know if it’s right, but it makes a lot of sense! I’ll check

  • Guy C is elgal, and you can be having a lot of fun with the pointers and etc... But if you are more in the mood to worry about the mechanics of the game itself, and not in machining as does a list, or other trivial data structure that in the background has nothing to do with the game, I suggest taking a look at Python, with the Pygame library - or even with the Allegro - I just checked that Allegro even comes with bindings for Python.

2 answers

0

One problem there (I can’t guarantee it is the only one) is that when there is an item removal, you advance twice to the next no: when doing the removal and another at the end of the while.

If the no removed is the last in the list, ant->Prox (and therefore no) will point to null , and just after the if you do no->dados.y += no->dados.vel; which must be the cause of your fault.

A solution is to run update and no advance only if no is 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;
    }

(Inserting the 'continue' command above passes the program stream immediately to the test of the while which is the right thing to do there: no is already pointing to what was before no->Prox.

0

It is not a solution, but a suggestion.

Why waste so much time using chained lists if you can use Arrays?

When one is learning one cannot forget the basics. To my see chained lists for a game does not make sense.

My suggestion would be to use in the structure Asteroide one bool which contains whether the asteroid is alive or not. Then with Arrays just draw and update the living.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.