2017-01-31 2 views
2

Я написал приложение Gtk + 3, которое анализирует некоторые изображения. После создания списка имен файлов я вызываю функцию (через кнопку обратного вызова), которая считывает изображения и выполняет некоторые операции. Все работает отлично, за исключением, когда я вычислить этот 4D-массив (то есть большой ~ 1 Gb):Неверные и случайные результаты после умножения в обратном вызове 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]; 
         } 
        } 
       } 
      } 
     } 

На самом деле в некоторых точках, которые не являются одинаковыми для каждого прогона (и часто целые строки), это дает нули хотя элементы A и B правильны и отличаются от нуля. Точно такой же код в версии командной строки работает отлично. Может кто-нибудь сказать мне, почему это происходит?

Пожалуйста, помогите!

EDIT 1

Здесь больше информации о коде.

 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

Как вы можете видеть, результаты разные, и эти нули элементы по-разному расположенные каждый раз, когда я исполняю программа.

+3

Если именно код, который вы опубликовали, работает изолированно, как мы должны выяснить, что случилось с другой ситуацией, в которой вы не дали нам никакого кода? Предоставьте [MCVE] (http://stackoverflow.com/help/mcve). – Phillip

+0

Существуют ли глобальные переменные, которые могут быть изменены при создании вашего массива? – Gerhardh

+0

@ Gerhardh Я написал код основных разделов, если это может быть полезно. – SimoneG

ответ

0

Случайные ошибки, подобные этим, в большинстве случаев являются симптомами типичных ошибок памяти C.

Я предлагаю вам использовать valgrind для отладки вашего программного обеспечения и поиска любых непреднамеренных адресов памяти (неправильного разыменования указателей, утечки памяти, ошибок памяти и т. Д.).

Вы можете найти хороший учебник here.

E.g. используйте libtool --mode=execute valgrind --tool=memcheck --log-file=ValgrindLog.log YourProgram для поиска утечек памяти или неправильного доступа к памяти (если вы используете libtool, конечно, иначе разделите команду libtool).

Смежные вопросы