2017-01-31 3 views
2

J'ai écrit une application Gtk + 3 qui analyse certaines images. Une fois la liste des noms de fichiers créée, j'appelle une fonction (via le bouton de rappel) qui lit les images et effectue certaines opérations. Tout fonctionne bien sauf quand je calcule ce 4D-tableau (qui est grand ~ 1 Gb):Résultats erronés et aléatoires après la multiplication dans un rappel gtk + 3

for(int i=0; i<Nimages; i=i+2){ 
     TIFF* tifA = TIFFOpen(impath[i], "r"); 
     TIFF* tifB = TIFFOpen(impath[i+1], "r"); 

     for (row = 0; row < length; row++){ 
      TIFFReadScanline(tifA, bufA, row,0); 
      TIFFReadScanline(tifB, bufB, row,0); 
      dataA=bufA; 
      dataB=bufB; 
      for(col = 0; col < width; col++){ 
       A[row][col] = dataA[col]; 
       B[row][col] = dataB[col]; 
      } 
     } 
     TIFFClose(tifA); 
     TIFFClose(tifB); 
     for (row = 0; row < length; row++){ 
      for (col = 0; col < width; col++){ 
       for (int x = 0 ; x < csiMax ; x++) { 
        for (int y = 0 ; y < psiMax ; y++){ 
         C[row][col][x][y] += A[row][col]*B[row+x][col+y]; 
         } 
        } 
       } 
      } 
     } 

En fait, dans certains points qui ne sont pas les mêmes pour chaque course (et souvent des lignes entières), il donne des zéros même si les éléments A et B sont corrects et différents de zéro. Exactement le même code, dans une version de ligne de commande, fonctionne très bien. Quelqu'un peut-il me dire pourquoi cela arrive?

S'il vous plaît, aidez-moi!

EDIT 1

Ici, plus d'informations du code.

 gdouble ****alloc4D (gint maxx, gint maxy,gint maxr,gint maxc) { 
      gdouble *rows = g_malloc0(maxx*maxy*maxr*maxc*sizeof(*rows)); 
      gdouble **cols = g_malloc0(maxx*maxy*maxr*sizeof(*cols)); 
      gdouble ***mat = g_malloc0(maxx*maxy*sizeof(*mat)); 
      gdouble ****result = g_malloc0(maxx*sizeof(*result)); 
      for (int x = 0 ; x < maxx ; x++) { 
       result[x] = mat; 
       mat += maxy; 
       for (int y = 0 ; y < maxy ; y++) { 
        result[x][y] = cols ; 
        cols += maxr; 
        for (int r = 0 ; r < maxr ; r++) { 
         result[x][y][r] = rows; 
         rows += maxc; 
        } 
       } 
      } 
      return result; 
     } 

     void free4D(gdouble ****Mat4D){ 
       g_free(Mat4D[0][0][0]); 
       g_free(Mat4D[0][0]); 
       g_free(Mat4D[0]); 
       g_free(Mat4D); 
     } 

void TIFFanalyzePairs(GtkWidget *widget, gpointer data){ 
    MYlist *plist=data; 
     long int Nimages=g_slist_length(plist->List); 
     long int Npairs=Nimages/2; 

     TIFF* tif = TIFFOpen((gchar*)g_slist_nth_data(plist->List,1), "r"); 
     uint32 length; 
     uint32 width; 
     tsize_t scanline; 
     tdata_t bufA; 
     tdata_t bufB; 
     uint16 *dataA; 
     uint16 *dataB; 
     int csiMax; 
     int psiMax; 
     int row; 
     int col; 
     TIFFGetField(tif, TIFFTAG_IMAGELENGTH,&length); 
     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH,&width); 
     TIFFClose(tif); 
     g_print("length %d pixel \n",length); 
     g_print("width %d pixel \n",width); 

     scanline = TIFFScanlineSize(tif); 
     bufA = _TIFFmalloc(scanline); 
     bufB = _TIFFmalloc(scanline); 

     g_print("--------------------------\n"); 

     plist->Am=(double**)malloc(length*sizeof(double*)); 
     plist->Bm=(double**)malloc(length*sizeof(double*)); 
     plist->SA=(double**)malloc(length*sizeof(double*)); 
     plist->SB=(double**)malloc(length*sizeof(double*)); 
     plist->A=(uint16**)malloc(length*sizeof(uint16*)); 
     plist->B=(uint16**)malloc(length*sizeof(uint16*)); 
     plist->u=(double**)malloc(length*sizeof(double*)); 
     plist->v=(double**)malloc(length*sizeof(double*)); 

     for(row=0; row<length; row++){ 
      plist->u[row]=(double*)malloc(width*sizeof(double)); 
      plist->v[row]=(double*)malloc(width*sizeof(double)); 
      plist->Am[row]=(double*)malloc(width*sizeof(double)); 
      plist->Bm[row]=(double*)malloc(width*sizeof(double)); 
      plist->SA[row]=(double*)malloc(width*sizeof(double)); 
      plist->SB[row]=(double*)malloc(width*sizeof(double)); 
      plist->A[row]=(uint16*)malloc(scanline); 
      plist->B[row]=(uint16*)malloc(scanline); 

     } 
/* HERE I OMITTED THE SECTION WHERE I COMPUTE Am, Bm, SA, SB BECAUSE IT'S RIGHT*/ 


     MEMORYSTATUSEX statex; 

     statex.dwLength = sizeof (statex); 
     GlobalMemoryStatusEx (&statex); 
     double memfree; 
     memfree=(double)statex.ullAvailPhys; 

     csiMax=plist->dtop+plist->ddown+1; 
     psiMax=plist->dleft+plist->dright+1; 

     double maxram=ceil(memfree*plist->Kmem); 
     double maxArraySize=maxram/(csiMax*psiMax*sizeof(double)*width); 
     double stepR=length/maxArraySize; 
     stepR=ceil(stepR); 
     long int row_step=ceil(length/stepR); 
     int *forstep=(int*)malloc(length*sizeof(int)); 

     forstep[0]=0; 
     long int dummy; 
     long int k=0; 
     for(row=1; row<length; row++){ 
      dummy=(row+1)%row_step; 
      if(dummy==0){ 
       k=k+1; 
       forstep[k]=row; 
      } 
     } 
     if(forstep[k]!=length-1){ 
      forstep[k+1]=length-1; 
      k=k+1; 
     } 
     g_print("rowstep %ld pixel\n", row_step); 
     for(int l=0; l<=k;l++){ 
      g_print("l=%d ->row=%d \n", l,forstep[l]); 
     } 

     gdouble **A=(gdouble**)g_malloc(length*sizeof(double*)); 
     for(row=0; row<length; row++){ 
      A[row]=(gdouble*)g_malloc(width*sizeof(gdouble)); 
     } 
     gdouble **Bneg; 
     Bneg=(gdouble**)g_malloc((csiMax+length)*sizeof(gdouble*)); 
     for(row=0; row<length+csiMax; row++){ 
      Bneg[row]=(gdouble*)g_malloc((width+psiMax)*sizeof(gdouble)); 
    } 


     for(row=0; row<length+csiMax; row++){ 
      for(col=0; col<width+psiMax; col++){ 
       Bneg[row][col]= log(-1); 
       } 
     } 

     gint csiNeg=plist->dtop; 
     gint psiNeg=plist->dleft; 


     for(int step=0; step<k; step++){ 
      gdouble ****C = alloc4D(row_step,width,csiMax,psiMax); 

      for(int i=0; i<Nimages-1; i=i+2){ 
       TIFF* tifA = TIFFOpen((gchar*)g_slist_nth_data(plist->List,i), "r"); 
       TIFF* tifB = TIFFOpen((gchar*)g_slist_nth_data(plist->List,i+1), "r"); 

       for (row = 0; row < length; row++){ 
        TIFFReadScanline(tifA, bufA, row,0); 
        TIFFReadScanline(tifB, bufB, row,0); 
        dataA=bufA; 
        dataB=bufB; 
        for(col = 0; col < width; col++){ 
         A[row][col] = (dataA[col]-plist->Am[row][col])/(plist->SA[row][col]); 
         Bneg[row+plist->dtop][col+plist->dleft] = (dataB[col]-plist->Bm[row][col])/(plist->SB[row][col]); 
        } 
       } 
       TIFFClose(tifA); 
       TIFFClose(tifB); 

       /* calcolo di C[x][y][r][c] */ 
       for (row = 0; row < row_step; row++){ 
        for (col = 0; col < width; col++){ 
         for (int x = 0 ; x < csiMax ; x++) { 
          for (int y = 0 ; y < psiMax ; y++){ 
           C[row][col][x][y] += A[row+forstep[step]][col]*Bneg[x+row+forstep[step]][y+col]; 
                  } 
         } 
        } 
       } 

      } 
/* HERE A SECTION THAT DEPENDS ON C[row][col][x][y] , SO I OMITTED BECAUSE THE PROBLEMS START CALCULATING C*/ 
     free4D(C); 
     } 

     _TIFFfree(bufA); 
     _TIFFfree(bufB); 
     free2D(A,length); 
     free2D(Bneg,length); 

     toc(t0); 


    } 



    int 
    main (int argc, 
      char **argv) 
    { 
     gtk_init (&argc, &argv); 
     GtkWidget *window; 
     GtkWidget *grid; 
     GdkPixbuf *icon; 
     GtkWidget *start_button; 
     GtkWidget *select_files_button; 
     GtkWidget *button; 


     MYlist datalist; 
     datalist.dtop=6;//csiNeg 
     datalist.dleft=3;//psiNeg 
     datalist.ddown=6;//csiPos 
     datalist.dright=30;//psiPos 
     datalist.Kmem=0.6; 


     /* create a new window, and set its title */ 
     window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 
     gtk_window_set_title (GTK_WINDOW (window), "SPEC beta"); 
     gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 
     gtk_window_set_default_size(GTK_WINDOW(window), 900, 700); 
     gtk_container_set_border_width (GTK_CONTAINER (window), 15); 

     grid = gtk_grid_new(); 

     gtk_container_add (GTK_CONTAINER (window), grid); 

     start_button = gtk_button_new_with_label ("Start"); 
     g_signal_connect (start_button, "clicked", G_CALLBACK (TIFFanalyzePairs), &datalist); 
     gtk_grid_attach (GTK_GRID (grid), start_button, 0, 0, 2, 1); 

     /* bottone selezione files con annessa finestra di dialogo (callback) */ 
     select_files_button = gtk_button_new_with_label ("Select files or folder"); 
     g_signal_connect (select_files_button, "clicked", G_CALLBACK (select_files), &datalist); 
     gtk_grid_attach (GTK_GRID (grid), select_files_button, 0, 1, 2, 1); 

     gtk_widget_show_all (window); 

     g_signal_connect(window, "destroy", 
      G_CALLBACK(gtk_main_quit), NULL); 
     g_object_unref(icon); 

     gtk_main(); 

     return 0; 
    } 

EDIT 2

The exact values of a C[row][col][:][:] calculated by the command line version of the code

The same matrix calculated by the code with Gtk

Comme vous pouvez le voir, les résultats sont différents et ces zéros éléments sont différemment situés à chaque fois que j'exécute la programme.

+3

Si exactement le code que vous avez posté fonctionne de manière isolée, comment pouvons-nous savoir ce qui ne va pas dans l'autre situation pour laquelle vous n'avez pas donné de code? Veuillez fournir un [MCVE] (http://stackoverflow.com/help/mcve). – Phillip

+0

Y a-t-il des variables globales impliquées qui pourraient être modifiées pendant que vous créez votre tableau? – Gerhardh

+0

@Gerhardh J'ai écrit le code des sections principales, si cela peut être utile. – SimoneG

Répondre

0

Les erreurs aléatoires comme celles-ci sont dans la plupart des cas des symptômes de bogues de mémoire C typiques. Je suggère que vous utilisiez valgrind pour déboguer votre logiciel et rechercher des accès mémoire non désirés (mauvais pointeur-déréférencement, fuite de mémoire, mauvaise mémoire, etc.).

Vous pouvez trouver un bon tutoriel here.

E.g. utilisez libtool --mode=execute valgrind --tool=memcheck --log-file=ValgrindLog.log YourProgram pour rechercher des fuites de mémoire ou un mauvais accès à la mémoire (si vous utilisez bien sûr libtool, sinon déposez la commande libtool).