c-在gtk+3回调中相乘后的错误和随机结果



我编写了一个Gtk+3应用程序,用于分析一些图像。一旦创建了文件名列表,我就会调用一个函数(通过回调按钮)来读取图像并进行一些操作。除了当我计算这个4D阵列(很大~1 Gb)时,一切都很好:

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元素是正确的并且与零不同,它也会给出零。在命令行版本中,完全相同的代码可以正常工作。有人能告诉我为什么会发生这种事吗?

求你了,帮帮我!

编辑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 pixeln", 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;
}

编辑2

由代码的命令行版本计算的C[行][列][:][:]的精确值

使用Gtk 代码计算的相同矩阵

正如你所看到的,结果是不同的,每次我执行程序时,这些零元素的位置都不同。

在大多数情况下,像这样的随机错误是典型C内存错误的症状。

我建议你使用valgrind来调试你的软件,并搜索任何意外的内存访问(错误的指针取消引用、内存泄漏、坏的内存释放等)。

你可以在这里找到一个好的教程。

例如,使用libtool --mode=execute valgrind --tool=memcheck --log-file=ValgrindLog.log YourProgram来搜索内存泄漏或错误的内存访问(当然,如果您使用libtool,则剥离libtool命令)。

最新更新