2012-04-25 5 views
-2

J'essaie d'obtenir une image mandelbrot clairement avec la programmation séquentielle en C++, mais j'obtiens une erreur de segmentation pendant l'exécution. Je n'ai aucune idée de la seg. faute, mais mon programme compile parfaitement sans erreur.erreur de segmentation

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

int file_write(unsigned int width, unsigned int height) 
{ 
    unsigned int **color = NULL; 
    FILE *fractal = fopen("mandelbrot_imageSequential.ppm","w+"); 
    if(fractal != NULL) 
    { 
     fprintf(fractal,"P6\n"); 
     fprintf(fractal,"# %s\n", "Mandelbrot_imageSequential.ppm"); 
     fprintf(fractal,"%d %d\n", height, width); 
     fprintf(fractal,"40\n"); 
     int x = 0, y = 0; 
     unsigned int R = 0, G = 0, B = 0; 
     for(x = 0; x < width; ++x) 
     { 
      for(y = 0; y < height; ++y) 
      { 
       R = (color[y][x]*10); 
       G = 255-((color[y][x]*10)); 
       B = ((color[y][x]*10)-150); 
       if(R == 10) 
        R = 11; 
       if(G == 10) 
        G = 11; 
       if(B == 10) 
        B = 11; 
       putc(R, fractal); 
       putc(G, fractal); 
       putc(B, fractal); 
      } 
     } 
     fclose(fractal); 
    } 
    return 0; 
} 
int method(int x, int y, int height, int width, double min_re, double max_re, double min_im, double max_im, int max_iterations) 
{ 
    double threshold = 4; 
    double x_factor = (max_re-min_re)/(width-1); 
    double y_factor = (max_im-min_im)/(height-1); 
    double c_im = max_im - y*y_factor; 
    double c_re = min_re + x*x_factor; 
    double Z_re = c_re, Z_im = c_im; 
    unsigned int col = 0; 
    for(unsigned n = 0; n < max_iterations; ++n) 
    { 
     double Z_re2 = Z_re*Z_re, Z_im2 = Z_im*Z_im; 
     if(Z_re2 + Z_im2 > threshold) 
     { 
      col = n; 
      break; 
     } 
     Z_im = 2 * Z_re * Z_im + c_im; 
     Z_re = Z_re2 - Z_im2 + c_re; 
    } 
    return col; 
} 
int main(int argc, char *argv[]) 
{ 
    unsigned int width; 
    unsigned int height; 
    unsigned int max_iterations; 
    unsigned int **color = NULL; 
    int x,y; 
    double threshold; 
    double min_re; 
    double max_re; 
    double min_im; 
    double max_im; 
    unsigned int NUM_OF_THREADS; 
    if(argc != 10) 
    { 
     printf("There is an error in the input given.\n"); 
     return 0; 
    } 
    else 
    { 
     height = atoi(argv[1]); 
     width = atoi(argv[2]); 
     max_iterations = atoi(argv[3]); 
     min_re = atof(argv[4]); 
     max_re = atof(argv[5]); 
     min_im = atof(argv[6]); 
     max_im = atof(argv[7]); 
     threshold = atoi(argv[8]); 
     NUM_OF_THREADS = atoi(argv[9]); 
    } 
    color = (unsigned int**)malloc(height*sizeof(unsigned int*)); 
    printf("height = %d\twidth = %d\tmaximum_iterations = %d\tminimum_x-value = %.2f\tmaximum_x-value = %.2f\tminimum_y-value = %.2f\tmaximum_y-value = %.2f\tthreshold_value = %.2f\tno. of threads = %d\t\n",height,width,max_iterations,min_re,max_re,min_im,max_im,threshold,NUM_OF_THREADS); 
    for(x = 0; x < height; x++) 
    { 
     color[x] = (unsigned int*)malloc(width*sizeof(unsigned int)); 
    } 
    time_t ts,te; 
    time(&ts); 
    method(x,y,height,width,min_re,max_re,min_im,max_im,max_iterations); 
    time(&te); 
    double diff = difftime(te,ts); 
    file_write(width, height); 
    printf("Total Time elapsed: %f\n",diff); 
    return 0; 
} 

Comment corriger cette erreur de segmentation?

+1

Laissez votre débogueur trouver le spot de segfault. – Anthales

+0

ok, je vais l'essayer. –

+3

Je pourrais repérer un problème dans votre 'file_write': vous n'allouez jamais de mémoire pour votre' unsigned int ** color' ou plutôt, vous n'avez pas passé la 'couleur' de votre main à la fonction. – Anthales

Répondre

2

Au moins un problème est dans la fonction file_write.

  1. unsigned int **color = NULL;
  2. R = (color[y][x]*10);

Je suppose que la couleur doit être un paramètre d'entrée.

+0

puis-je savoir quelle est la solution pour ce défaut seg? –

+0

Bien sûr. 1. 'int file_write (largeur int sans signe, hauteur int, unsigned int ** couleur) {...}', 2. 'file_write (largeur, hauteur, couleur);'. Mais il y a un autre problème. La couleur est allouée dans la main, non initialisée et n'est utilisée nulle part, c'est-à-dire que la fonction 'file_write' enregistre quelque chose. – megabyte1024

+0

maintenant j'essaie de l'exécuter sur le compilateur C au lieu de l'exécuter C++, il montre une erreur et note > erreur: les déclarations initiales de la boucle 'for' ne sont autorisées qu'en mode C99 > note: utiliser l'option -std = c99 ou -std = gnu99 pour compiler votre code –

1

Si vous êtes sur la machine Linux effectuer les opérations suivantes:

$ulimit -c unlimited 

Lancez ensuite le code. Notez qu'un fichier core. [Pid] est généré. allumez gdb comme suit

$gdb ./your_app core.[pid] 

Il vous prendra l'instruction où segfault s'est produite. émettre une commande "backtrace" dans l'invite gdb pour voir la hiérarchie des appels. N'oubliez pas de compiler avec l'indicateur "-g" pour obtenir plus de résultats gdb verbeux.

+0

J'ai essayé de lancer gdb mais il dit qu'il n'y a pas un tel fichier ou répertoire ... –

+0

quels arguments avez-vous fournis à gdb? êtes-vous dans le répertoire où réside votre binaire? avez-vous vérifié l'existence du fichier "core"? – Aftnix

+0

ouais je suis dans mon répertoire ... –

0

Il y a deux problèmes majeurs avec votre code:

  1. Vous allouer de la mémoire pour le tableau color mais utiliser un autre color l'intérieur file_write() qui est initialisé à NULL.

    Vous devez passer le premier color comme argument à file_write():

    int main(...) 
    { 
        ... 
        file_write(color, width, height); 
        printf("Total Time elapsed: %f\n",diff); 
        return 0; 
    } 
    

    Et déclarer l'autre color comme argument pour file_write():

    int file_write(unsigned int **color, unsigned int width, unsigned int height) 
    { 
        /* unsigned int **color = NULL; // Removed */ 
        ... 
    
  2. Vous n'appeler method() fois et ne rien stocker dans color. Vous devez l'appeler en boucle. Quelque chose de semblable à:

    /* Untested */ 
    for (y = 0; y < height; y++) { 
        for (x = 0; x < width; x++) { 
         color[y][x] = method(x,y,height,width,min_re,max_re,min_im,max_im,max_iterations); 
        } 
    } 
    

Ensuite, bien sûr, vous devriez vérifier les valeurs de retour de malloc(), fopen(), fprintf(), fclose(), ... et vérifiez que les variables d'entrée ont des valeurs raisonnables et ainsi de suite .

J'ai aussi remarqué que vous passez width et height dans un ordre différent de file_write() et method(). Pour éviter de futurs maux de tête, je voudrais remplacer la fonction method() par method(x, y, width, height) afin que les arguments horizontaux et verticaux soient passés dans le même ordre.