1

I have this structure containing links to the same structure type (peca). The problem is that when I try and use peca->penext in a different function, the debugger shows that the structure peca is not linked to the next or previous. What am I doing wrong?

typedef struct peca{
    int index;
    int esquerda;
    int direita;
    int disponibilidade;
    struct peca *penext;
    struct peca *peant;
}PECA;

typedef struct mao{
    int index;
    int tamanho;
    PECA *ppeca;
    struct mao *pnext;
}MAO;

typedef struct jogada{
    int index;
    PECA *ppeca;
    struct jogada *pnext;
}JOGADA;

typedef struct jogo{
    int nr_maos;
    MAO *pmao;
    JOGADA *pjog;
}JOGO;

void init_jogada(JOGADA *pj) {
pj->ppeca = (PECA *) malloc(sizeof(PECA) * 28);
PECA *paux = pj->ppeca;
  for (int i = 0; i < 28; ++i) {
    paux->index = i;
    paux->disponibilidade = 1;
    if (i == 0)
    {
        paux->peant = NULL;
        paux->penext = paux++;
    }
    else if (i == 27)
    {
        paux->peant = paux--;
        paux->penext = NULL;
    }
    else
    {
        paux->penext = paux++;
        paux->peant = paux--;
    }
    paux++;
  }


}
clearlight
  • 12,255
  • 11
  • 57
  • 75

2 Answers2

3

The way you increment pointers to PECA is just cunfusing, that's probably what is breaking your code. Since I speak Portuguese, I can tell peant means pelast, so I can infer it is a double linked list.

Your double Linked List is absolutely redundant since your pieces (PECA is piece in english) are in a array. Linked lists are used to iterate over a sequence where items are stored sparse on memory, arrays put items next to each other, that's why you can dereference items with a index.

This is what I think you are doing worng:

    paux->penext = paux++; 
    /* Here you set the next, why increment the pointer while assigning?
       paux++ changes the value of paux. You might not want that here */

Maybe you are not aware that paux++ or ++paux or paux-- or --paux does change where paux point to.

This is your code corrected:

  for (int i = 0; i < 28; ++i) {
    paux->index = i;
    paux->disponibilidade = 1;
    if (i == 0)
    {
        paux->peant = NULL;
        paux->penext = paux +1;
    }
    else if (i == 27)
    {
        paux->peant = paux - 1;
        paux->penext = NULL;
    }
    else
    {
        paux->penext = paux + 1;
        paux->peant = paux - 1;
    }
    /* Ok! Now we really want to increment paux, to use in the next iteration */
    paux++;
  }
Felipe Lavratti
  • 2,887
  • 16
  • 34
1

As a general rule, Ddn't make special cases in the for loop. Take the code inside if (i==0) and put it before the loop, and the code inside if (i==27) outisde the loop. It makes the loop itself more simple to the reader and avoid problems in case you change the number of iterations and forget to change the conditions.

Your code will look much simpler if you don't modify paux inside the loop. Use the iterator i to access the objects. If you really want to use paux to simplify your syntax, either make it the iterator or assign it at the beginning of the loop:

paux = pj->ppeca + i;

Then you can find the next and the previous with paux + 1 and paux - 1.

But do you really need next/previous pointers? Without seeing the rest of the code, this may sound a silly question to you, but why do you have a structure that resembles a doubly-linked list when your elements are already allocated into an array?

giusti
  • 3,156
  • 3
  • 29
  • 44