2016-04-12 3 views
1

Je vais avoir du mal à comprendre pourquoi les 2 pointeurs du conseil d'administration pointent vers le même emplacement mémoire, suivant est ma situation dans mon game.c:memcpy problème lors de la copie d'un pointeur vers une struct

int game_state_transition(const struct state * s0, const struct move * m, struct state * s1) { 
    memcpy(s1, s0, sizeof(struct state)); 
    memcpy(s1->board, s0->board, sizeof(struct move ***)); 
    if (game_update(s1, m)){ 
     printf("%p\n", s1->board); 
     printf("%p\n", s0->board); 
     game_print(s0); 
     s1->next = s0; 
     return 1; 
    } 

    return 0; 

et voici mon game.h:

struct state { 
    struct player * current_player; 
    struct move *** board; 
    enum game_status status; 
    const struct state * next; }; 

Je comprends que, après la première memcpy les 2 pointeurs du conseil d'administration pointent vers le même emplacement en mémoire, mais je ne comprends pas le comportement du second.

Merci pour l'aide

+3

Ah, un programmeur trois étoiles. – EOF

+1

'sizeof (struct move ***)' a la mauvaise taille. Cependant, il suffit de mettre 's1-> board' pour égaler' s0-> board' (avec le premier memcpy), donc le second memcpy provoque un comportement indéfini puisqu'il a la même source et la même cible.Vous n'avez pas dit ce que vous essayez de faire mais je suppose que vous essayez de faire une copie du tableau, au lieu d'avoir un tableau avec deux pointeurs pointant vers lui? (Si c'est le cas, mettez à jour votre question pour inclure cette information et montrez également comment vous répartissez le tableau en premier lieu). –

+0

Vous aussi n'a pas dit quel comportement vous avez observé de la deuxième memcpy (ni ce que vous vous attendiez à faire). –

Répondre

1

premier appel memcpy fait ce s1 souligne, être la même chose que les points à s0. De ce point S0-> Conseil et S1-> carte a la même valeur de pointeur

memcpy(s1, s0, sizeof(struct state)); 

exemple:

avant l'appel:
S0-> joueur = 0x000100
S0-> move = 0x000200
S0-> status = 1
S0-> state = 0x000300

S1-> joueur = 0x000400
S1-> move = 0x000500
S1-> status = 2
S1-> state = 0x000600

après appel:
S0-> joueur = 0x000100
S0-> move = 0x000200
S0- > status = 1
S0-> state = 0x000300

S1-> joueur = 0x000100
S1-> move = 0x000200
S1-> status = 1
s1-> état = 0x000300

Pour la deuxième memcpy, il y a plus de problèmes.

memcpy(s1->board, s0->board, sizeof(struct move ***)); 

D'abord, vous envoyez le pointeur, de sorte que le terme correct serait sizeof (struct déplacer **), mais elle donnera la même taille, puisque tous les pointeurs ont la même taille.

Si vous souhaitez créer une nouvelle copie (afin de conserver l'état précédent), vous devez d'abord allouer de la mémoire.

Il n'est pas fréquent de voir trois étoiles dans la programmation C, mais cela arrive. Tout dépend de la logique nécessaire et du nombre de niveaux de changements possibles dans la pile d'appel. Le plus commun est 1 et 2 (vous donnant le pointeur direct, et une référence à un pointeur qui peut être changé à partir d'un point externe)