2017-09-05 2 views
0

J'ai écrit un code C pour mélanger un jeu de 52 cartes en utilisant la logique de permutation. Le code génère un nombre aléatoire compris entre 0 et 53 (52 et 53 sont omis), puis l'échange avec l'index ith du tableau. Le code est ci-dessous.segfault SEGV_ACCERR - Permissions non valides pour l'objet

Mon numéro: Lorsque je commente l'appel de la fonction display() avant d'appeler la fonction swap(), le programme génère une erreur seg. Mais quand je le décommente et appelle la fonction d'affichage avant d'appeler la fonction swap(), le programme fonctionne bien et j'obtiens la sortie désirée. Je ne sais pas pourquoi cela se passe.

Fonction principale:

int main() 
{ 
char deck[] = {'2','3','4','5','6','7','8','9','0','A','J','K','Q'}; 
char suit[] = {'D','H','S','C'}; 

char **array,**array1; 
array = malloc(sizeof(char *)*52); 
array1= array; 

srand(time(NULL)); 

for(int i=0;i<=12;i++) 
{ 
     for(int j=0;j<=3;j++) 
     { 
       if((*array = malloc(sizeof(char)*2))!=NULL) 
       { 
         sprintf(*array,"%c%c",deck[i],suit[j]); 
         *array++; 
       } 
     } 
} 

//display(array1); // when i comment this line, the program throws segfault. when i uncomment it the program runs fine. 
swap(array1); 
display(array1); 
free_array(array1); 
return 0; 
} 

Et voici l'autre échange et l'affichage des fonctions.

void display(char **array) 
{ 
char **temp; 
temp = array; 

for(int i=0;i<=51;i++) 
{ 
     printf("temp [%s]\n",*temp); 
     *temp++; 
} 

return; 
} 

void swap(char **array) 
{ 
char **temp; 
int x; 
temp = array; 
char *temp1; 

for(int i=0;i<=51;i++) 
{ 
     x = rand()%53; 
     if(x == 53 || x == 52) 
       continue; 

     memcpy(temp1,temp[i],2); // program segfaults here. 
     memcpy(temp[i],temp[x],2); 
     memcpy(temp[x],temp1,2); 
} 
return; 
} 
+1

'temp1'is jamais initialisées, ni est' temp'. –

+0

@MichaelWalz 'temp = array;' l'initialise. Vous avez raison à propos de 'temp1'. – Barmar

Répondre

2

En fonction de swap -

Vous utilisez temp1 avec en initialisant.

void swap(char **array) 
{ 
    char **temp; 
    int x; 
    temp = array; 
    char temp1[ 2 ]; 

    for(int i=0;i<=51;i++) 
    { 
     x = rand()%53; 
     if(x == 53 || x == 52) 
       continue; 

     // need to multiply the indexes by 2 
     // allowing for the suit and deck 
     memcpy(temp1,temp[ i ],2); // program segfaults here. 
     memcpy(temp[ i ],temp[ x ],2); 
     memcpy(temp[ x ],temp1,2); 
    } 
} 

La figure ci-dessus montre que temp1 a été initialisé correctement.

Je n'ai pas vérifié le reste de votre fonction, mais cela arrêtera le segfault.

+0

J'ai compris. Mais comment appeler la fonction display() avant d'appeler la fonction swap() supprime ce problème? Becuase quand j'appelle la fonction d'affichage() avant d'appeler la fonction de swap(), je n'obtiens pas la faute de seg. Aussi, pourquoi le compilateur ne me donne pas un avertissement que la variable n'est pas initialisée avant son utilisé? – Shri

+0

@Shri: 'temp1' a un contenu indéfini/aléatoire. Selon l'utilisation précédente de l'emplacement de stockage, cela peut être NULL, -1 ou l'adresse d'un poème. – Gerhardh

+0

@Shri Activez-vous tous les avertissements lors de la compilation? – Gerhardh

1

Vous avez une autre UB et

sprintf(*array,"%c%c",deck[i],suit[j]);

vous avez besoin de 3 caractères non deux comme malloc:

*array = malloc(sizeof(char)*2))

+0

voulez-vous dire pour le terminateur null '\ 0'? – Shri