2016-08-26 2 views
2

Mon programme fonctionne si je ne libère pas la mémoire que j'ai allouée dinamiquement, mais quand j'essaie de la libérer, elle plante. Je cours mon code sur Dev-C++ et le message d'erreur n'est pas utile: un problème a fait arrêter le programme. Le problème se situe à la fin du code. Si je prends de la partie de libération, le programme fonctionne très bien. Voici une entrée de l'échantillon:Mon programme se bloque lors de l'utilisation de la fonction libre (C) sur le tableau

5 
2.3 
1.4 8.2 
3.1 2.0 7.7 
5.3 6.1 4.4 1.2 
5.5 6.1 3.0 2.3 4.9 

Le code:

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 

int main(void) { 
    int ordem; 
    scanf("%d", &ordem); 
    double **vetor; //apontador para apontador (jagged array) 
    double soma = 0; 
    int elementos; 
    elementos = (ordem*ordem + ordem)/2; 
    vetor = malloc(ordem * sizeof(double*)); //o primeiro endereço do vetor é seu local de memória, que define quantos pointers ele terá (ordem) 
    int n, m; 
    for (n = 0; n < ordem; n++) { 
     *(vetor + n) = malloc(n * sizeof(double)); 
    } 
    for (n = 0; n < ordem; n++) { 
     for (m = 0; m <= n; m++) { 
      scanf("%lf", *(vetor + n) + m); 
      soma = soma + *(*(vetor + n) + m); 
     } 
    } 
    double media = soma/(double) elementos; 
    double aux = 0; 
    for (n = 0; n < ordem; n++) { 
     for (m = 0; m <= n; m++) { 
      aux = aux + pow((media - vetor[n][m]), 2); 
     } 
    } 
    double desvio = sqrt(aux/((double)elementos)); 
    for (n = 0; n < ordem; n++) { 
     for (m = 0; m <= n; m++) { 
      printf("%.12lf ", (vetor[n][m] - media)/desvio); 
     } 
     printf("\n"); 
    } 
    printf("\n%.12lf %.12lf \n", media, desvio); 

    for (n = 0; n < ordem; n++) { 
     free(*(vetor + n)); 
    } 
    free(vetor); 

    return 0; 
} 

Et c'est à peu près tout. Je ne sais pas comment réparer ça. Je ne pense pas que le dealloc ait le même effet. Je préfère rester libre. Nouvelles informations que j'ai découvert: pour l'entrée d'échantillon, je peux libérer ((vetor + 0)), ( (vetor + 1)) et (* (vetor + 2)), mais pas 3 et 4. Cela signifie que le vecteur en quelque sorte a un problème sur ces deux.

+0

Votre problème avec 'free' est généralement dû à un type de débordement ailleurs dans votre code. Je regarderai. –

+3

'malloc (n * sizeof (double));' - ce serait une allocation zéro sur la première itération de votre boucle d'allocation. Je ne suppose pas de changer cela en 'malloc ((n + 1) * sizeof (double));' fait une différence, d'autant plus que vous * lisez * dans cet endroit avec 'm = 0; m <= n' comme init/conditionnel de votre boucle interne. – WhozCraig

+0

@ DavidC.Rankin Vous avez raison! Je n'alloue rien sur cette première boucle. C'est probablement un problème. Ça a marché! Merci mec! –

Répondre

3

Modifier ceci:

for (n = 0; n < ordem; n++) { 
    *(vetor + n) = malloc(n * sizeof(double)); 
} 

à ceci:

for (n = 0; n < ordem; n++) { 
    *(vetor + n) = malloc((n + 1) * sizeof(double)); 
} 

La raison est que n est égal à zéro dans la première itération, de sorte que vous demandez malloc() d'allouer zéro octets pour vous ..

BTW, voici ce que j'utilise habituellement pour ne pas faire ce genre d'erreurs: 2d-dynamic-array-c.

Sortie:

C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c 
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
5 
2.3 
1.4 8.2 
3.1 2.0 7.7 
5.3 6.1 4.4 1.2 
5.5 6.1 3.0 2.3 4.9 
-0.892202112506 
-1.307537578672 1.830552610141 
-0.523015031469 -1.030647267895 1.599810684493 
0.492249441383 0.861436522419 0.076913975216 -1.399834348932 
0.584546211642 0.861436522419 -0.569163416599 -0.892202112506 0.307655900864 

4.233333333333 2.166923061753 
C02QT2UBFVH6-lm:~ gsamaras$ 
+1

Battez-moi par '3-mins' ...':) ' –

+0

Que voulez-vous dire pas upvote':) ', travaille encore sur un peu d'une réponse. –

+0

Oh non, votre réponse était la réponse. Ce '(n + 1)' fait toute la différence. Le reste n'est que d'autres améliorations autour du problème principal. –

3

Vous avez déjà reçu votre réponse, mais il y a plusieurs autres domaines où vous avez vraiment besoin de validate votre entrée et les allocations si vous allez avoir toute confiance votre code travaille avec des valeurs réelles et ne pas écrire dans des parties inconnues de la mémoire de votre matériel. Toujours, toujours, validez l'entrée utilisateur et l'allocation de mémoire. Juste quelques lignes supplémentaires de code peuvent aider, par exemple:

int ordem; 
if (scanf ("%d", &ordem) != 1) { 
    fprintf (stderr, "error: invalid input (ordem)\n"); 
    return 1; 
} 
double **vetor, 
     soma = 0; 
int elementos, n, m; 

elementos = (ordem * ordem + ordem)/2; 
if (!(vetor = malloc (ordem * sizeof *vetor))) { 
    fprintf (stderr, "error: virtual memory exhausted.\n"); 
    return 1; 
} 

for (n = 0; n < ordem; n++) 
    if (!(*(vetor + n) = malloc ((n + 1) * sizeof **vetor))) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; 
    } 

for (n = 0; n < ordem; n++) { 
    for (m = 0; m <= n; m++) { 
     if (scanf ("%lf", *(vetor + n) + m) != 1) { 
      fprintf (stderr, "error: invalid input (vetor + %d)\n", n); 
      return 1; 
     } 
     soma = soma + *(*(vetor + n) + m); 
    } 
} 

Bonne chance avec votre codage.