2010-11-19 5 views
1

S'il vous plaît quelqu'un peut trouver un bug sur ce code? J'essaye de créer une fonction pour calculer un déterminant d'une matrice nXn. Le programme fonctionne normalement, mais une chose «sobrenatural» se produit. Je déclare la variable 'ch' de type 'char' et je n'en ai plus besoin. Mais si je supprime cette variable une occurrence d'erreur d'exécution. Pourquoi?bug le plus étrange jamais trouvé avec un programme récursif pour calculer un déterminant d'une matrice

/*the function 'pot' calculate a integer pow of a integer*/ 
int determinante(int** matriz , int dimensao){ 
    char cc;/*remove this variable and execute the code. On my PC a error occurr*/ 
    int cont = dimensao; 
    int det = 0; 
    int i, j, k, aux; 
    int** matriz_aux; 
    if(cont > 1){ 
     cont --; 
     for(i = 0; i < dimensao; i++){ 
      matriz_aux = (int**) malloc(cont * sizeof(int*)); 
      if(matriz_aux == NULL){ 
       printf("ERRO!\n"); 
       exit(-3); 
      } 
      for(j = 0; j < cont; j++){ 
       *(matriz_aux + j) = (int*) malloc(cont * sizeof(int)); 
       if(*(matriz_aux + j) == NULL){ 
        printf("ERRO!\n"); 
        exit(-4); 
       } 
      } 
      for(j = 0; j < cont; j++){ 
        for(k = 0, aux = 0; k < dimensao; k++){ 
         printf("Aqui\n"); 
         if(i != k){ 
          printf(" i = %d\n", i); 

          /*I forgive to add 'j' in '*(*(matriz + 1 + j) + k). Now it works but the bug stay here*/ 

          *(*(matriz_aux + j) + aux) = *(*(matriz + 1 + j) + k); 
          aux++; 
         } 
        } 
      } 
      det += matriz[0][i]*pot(-1, i)*determinante(matriz_aux, cont); 
     } 
    } 
    else { 
     det += matriz[0][0]; 
    } 

    for(i = 0; i < cont; i++){ 
     free(matriz_aux[i]); 
    } 
    free(matriz_aux); 
    //printf(" determinant value = %d\n", det); 
    return det; 
} 
+1

Modifiez la syntaxe du pointeur en syntaxe de tableau. Au lieu de * (matriz_aux + j) et * (* (matriz_aux + j) + aux), utilisez matrix_aux [j] et matriz_aux [j] [aux]. Le rend beaucoup plus lisible. – Axn

Répondre

2

Quelle est l'erreur? Si la suppression de cette variable provoque des problèmes, vous êtes probablement en train de déborder la pile. Essayez de le définir à une valeur comme 0xAB au début de la fonction, puis imprimez-le à la fin. Si cela a changé, vous avez un problème avec votre code.

+0

il est impossible d'être un débordement de pile. comment une variable de plus peut-elle déborder? – adriano

+0

Avec 'cc' en place, vous risquez de déborder ce seul octet. Sans 'cc', vous finissez par écrire dans la pile au lieu de la variable inutilisée. Vous pouvez garder 'cc' en place et faire en sorte que le débogueur interrompe une écriture sur cet octet pour tester cette théorie. – tomlogic

2
*(matriz_aux + j) = (int*) malloc(cont * sizeof(int)); 
/*...*/ 
*(*(matriz_aux + j) + aux) = *(*(matriz + 1) + k); 

aux peut être égal à cont, ce qui en fait la deuxième déclaration ci-dessus un dépassement de mémoire tampon. C'est un comportement indéfini, donc il pourrait ou ne pourrait pas planter. Tout peut provoquer un changement.

+0

Dans ce cas, par exemple, aux peut être égal à cont? Je ne peux pas voir ça. – adriano

1

Vous avez une fuite de mémoire importante. Vous allouez de la mémoire pour la matrice auxiliaire dimension fois dans la boucle. Mais vous ne le libérez qu'une seule fois. Changez votre logique d'allocation pour ne faire que l'allocation une fois.

+0

est correct. Vous devriez allouer 'matriz_aux' et les pointeurs dedans une seule fois, en dehors de la boucle' for (i = 0 ... '. – tomlogic

0

J'ai résolu le problème. Peut-être avec l'utilisation de gratuit à la fin du code. J'essaie la mémoire libre non allouée. Le code est correct:

int determinante(int** matriz , int dimensao){ 
    int cont = dimensao; 
    int det = 0; 
    int i, j, k, aux; 
    int** matriz_aux; 
    if(cont > 1){ 
     cont --; 
     for(i = 0; i < dimensao; i++){ 
      printf(" i inicial = %d\n", i); 
      matriz_aux = (int**) malloc(cont * sizeof(int*)); 
      if(matriz_aux == NULL){ 
       printf("ERRO!\n"); 
       exit(-3); 
      } 
      for(j = 0; j < cont; j++){ 
       *(matriz_aux + j) = (int*) malloc(cont * sizeof(int)); 
       if(*(matriz_aux + j) == NULL){ 
        printf("ERRO!\n"); 
        exit(-4); 
       } 
      } 
      for(j = 0; j < cont; j++){ 
        for(k = 0, aux = 0; k < dimensao; k++){ 
         if(i != k){ 
          printf("valor de i = %d\n", i); 
          *(*(matriz_aux + j) + aux) = *(*(matriz + j + 1) + k); 
          aux++; 
         } 
        } 
      } 
      det += matriz[0][i]*pot(-1, i)*determinante(matriz_aux, cont); 
     } 
     /*Is here that shoud be free 'matriz_aux'*/ 
     for(i = 0; i < cont; i++){ 
      free(matriz_aux[i]); 
     } 
     free(matriz_aux); 
    } 
    else { 
     det += matriz[0][0]; 
    } 

    /*for(i = 0; i < cont; i++){ 
     free(matriz_aux[i]); 
    } 
    free(matriz_aux);*/ 
    return det; 
} 

/*here is the function 'pot'*/ 


int pot(int x , int y){ 
    int result; 
    if(y == 0){//base case 
     result = 1; 
    } 
    else if(y > 0){ 
     result = x*pot(x , y-1);//inductive step 
    } 
    else if(x == 0){ 
     printf("ERRO!\n"); 
     exit(-1); 
    } 
    return result; 
} 

Remercions pour les réponses!

Questions connexes