Isla Geschrieben 20. Juli 2010 Geschrieben 20. Juli 2010 Hallo liebe Fachinformatiker, bei folgendem Problem bin ich an meine Grenzen gestoßen. Es handelt sich hierbei um einen Auszug aus einem 17 Jahre alten Code, der bisher auf 32-bit-Systemen fehlerlos lief. Aufgrund größerer Datenmengen, soll dieser nun auf 64-bit-Systemen laufen, was er leider aber nicht tut. Es wird ein "Speicherzugriffsfehler" gemeldet und natürlich frühzeitig abgebrochen. Leider kenne ich mich mit der 32-bit/64-bit Problematik nicht aus. Ich habe bereits versucht mich schlau zu lesen und fand, dass es häufig Probleme mit "sizeof()" gibt, da die Größen gleicher Variablentypen auf 32 und 64-bit Systemen nicht immer gleich sind. Wenn man jetzt davon ausgeht, dass man vor 17 Jahre eine Gleichheit von sizeof(int)=sizeof(int *) auf 32-bit-Systemen annahm, die heute auf 64-bit-Systemen nicht mehr stimmt, kann ich mir vorstellen, dass an dieser Stelle "ungenau" gearbeitet worden ist. Jedoch reichen hier meine Kenntnisse nicht mehr aus, um den Fehler auch zu finden. Kann mir jemand einige Tipps geben? Liege ich mit meiner Vermutung mit sizeof() überhaupt richtig? Ich danke für alle Antworten! Isla #include <stdio.h> #include <stdlib.h> #include <netcdf.h> #include "main.h" #include "error.h" extern "C" { #include "tri_netcdf.h" #include "tri_netcdf_p.h" #include "tripdat_netcdf.h" #include "netcdf_info.h" } #include "mmemory.h" #include "tri_io.h" #define NO_HISTBYTES_PER_TRI "histbytes_per_tri" #define HIST_STACK "history_stack" #define HIST_LEN "history_depth" #define HIST_STAT "history_status" /******************************************************************************* * Description: *******************************************************************************/ void read_triangulation(char *name){ int i, j, n, npoints, ntriangles; int cdfid, tri_points_var, tri_neighbours_var, points_xc_var, points_yc_var; int points_bdry_var, hist_bytes = 0, bsize; int hist_bytes_var=0, hist_depth_var=0, hist_stat_var=0; Point *pt, **pt_ptr; Triangle *tri, **tri_ptr; NetcdfInfo info; void *buffer; long (*three_long_buf)[3]; double *double_buf; unsigned char *byte_buf; short *short_buf; long *long_buf; if(!nctri_open_tri_file(name, global_parameter.tri_name, &i, &ntriangles, &npoints, &cdfid, &tri_points_var, &tri_neighbours_var, &points_xc_var, &points_yc_var, &points_bdry_var, &info)){ fprintf(stderr, "ERROR:\nCannot open netCDF file\n'%s'!\nWrong type?", name); exit(EXIT_FAILURE); } if((i = netcdf_dim_no(&info, NO_HISTBYTES_PER_TRI)) >= 0){ hist_bytes = (int)info.dim[i].size; if(hist_bytes > HIST_CHARS) fatal_error("Triangulation needs larger history stack than supported!"); } if(hist_bytes){ if((hist_bytes_var = netcdf_var_no(&info, HIST_STACK)) < 0) fatal_error("Missing variable with name " HIST_STACK); if((hist_depth_var = netcdf_var_no(&info, HIST_LEN)) < 0) fatal_error("Missing variable with name " HIST_LEN); if((hist_stat_var = netcdf_var_no(&info, HIST_STAT)) < 0) fatal_error("Missing variable with name " HIST_STAT); } triangulation.ntriangles = ntriangles; triangulation.npoints = npoints; triangulation.triangle = NULL; triangulation.point = NULL; bsize = hist_bytes * triangulation.ntriangles * (int)sizeof(unsigned char); if(3 * triangulation.ntriangles * (int)sizeof(long) > bsize) bsize = 3 * triangulation.ntriangles * (int)sizeof(long); if(triangulation.npoints * (int)sizeof(double) > bsize) bsize = triangulation.npoints * (int)sizeof(double); if((buffer = malloc(bsize)) == NULL) fatal_error("Out of memory!"); if((pt_ptr = (Point **)malloc(npoints * sizeof(*pt_ptr))) == NULL) fatal_error("Out of memory!"); for(i = 0; i < npoints; i++){ pt = alloc_point(); pt->succ = triangulation.point; triangulation.point = pt; } for(i = 0, pt = triangulation.point; i < npoints; i++, pt = pt->succ) pt_ptr[i] = pt; if((tri_ptr = (Triangle **)malloc(ntriangles * sizeof *tri_ptr)) == NULL) fatal_error("Out of memory!"); for(i = 0; i < ntriangles; i++){ tri = alloc_triangle(); tri->succ = triangulation.triangle; triangulation.triangle = tri; } for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ) tri_ptr[i] = tri; if(hist_bytes){ long start[2] = {0, 0}, count[2]; int max_hist = 0; byte_buf = (unsigned char *)buffer; count[0] = ntriangles; count[1] = hist_bytes; ncvarget(cdfid, hist_bytes_var, start, count, buffer); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ){ for(j = 0; j < hist_bytes; j++) tri->hist.hist[j] = byte_buf[hist_bytes * i + j]; } ncvarget(cdfid, hist_stat_var, start, count, buffer); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ){ tri->hist.green = byte_buf[i] & 1; tri->hist.green_ngb = (byte_buf[i] >> 1) & 3; } short_buf = (short *)buffer; ncvarget(cdfid, hist_depth_var, start, count, buffer); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ){ tri->hist.depth = short_buf[i]; if(tri->hist.depth > max_hist) max_hist = tri->hist.depth; } printf("Maximum history size in triangulation: %d\n", max_hist); printf("(Maximum possible = %d)\n", HIST_DEPTH); } else{ for(tri = triangulation.triangle; tri != NULL; tri = tri->succ){ tri->hist.depth = 0; tri->hist.green = FALSE; } } long_buf = (long *)buffer; nctri_read_tri_pkt_bdry(cdfid, points_bdry_var, long_buf, 0, npoints); for(i = 0; i < npoints; i++) pt_ptr[i]->bdry = (short)long_buf[i]; double_buf = (double *)buffer; nctri_read_tri_pkt_x_or_y_c(cdfid, points_xc_var, double_buf, 0, npoints); for(i = 0; i < npoints; i++) pt_ptr[i]->x[0] = double_buf[i]; nctri_read_tri_pkt_x_or_y_c(cdfid, points_yc_var, double_buf, 0, npoints); for(i = 0; i < npoints; i++) pt_ptr[i]->x[1] = double_buf[i]; for(n = 0, pt = triangulation.point; pt != NULL; pt = pt->succ) pt->n = n++; for(n = 0, tri = triangulation.triangle; tri != NULL; tri = tri->succ) tri->n = n++; three_long_buf = (long (*)[3])buffer; nctri_read_tri_pts_or_nbs(cdfid, tri_points_var, three_long_buf, 0, ntriangles); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ) for(j = 0; j < 3; j++) tri->pnt[j] = pt_ptr[three_long_buf[i][j]]; nctri_read_tri_pts_or_nbs(cdfid, tri_neighbours_var, three_long_buf, 0, ntriangles); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ) for(j = 0; j < 3; j++) tri->ngb[j] = three_long_buf[i][j] < 0 ? NULL : tri_ptr[three_long_buf[i][j]]; free(tri_ptr); free(pt_ptr); free(buffer); ncclose(cdfid); } /*** read_triangulation() ***/ Zitieren
Bubble Geschrieben 20. Juli 2010 Geschrieben 20. Juli 2010 An welcher Stelle bricht das Programm denn genau ab? Welcher Compiler wird verwendet, was ist das Zielsystem? Schon mal mir einem Debugger Schritt für Schritt durchgegangen? Zitieren
flashpixx Geschrieben 20. Juli 2010 Geschrieben 20. Juli 2010 sifeof liefert ja nur die Größe eines Datentyps zurück, das ist ja ja unter 32 oder 64 Bit Systemen erst mal egal, sofern man es korrekt macht. Das hier ist ein kleiner Einblick Converting 32-bit Applications Into 64-bit Applications: Things to Consider in das Thema. Der Ansatz von Bubble ist sicher auf jeden Fall richtig, ohne jetzt den Code im Detail durch zu schauen, würde ich einmal auf Casts tippen. Außerdem sollte man meines Wissens Rückgaben von malloc nicht casten. Ich denke, um das Debuggen wirst Du nicht herum kommen. Außerdem wären natürlich Quellcode Kommentare hilfreich Zitieren
Isla Geschrieben 20. Juli 2010 Autor Geschrieben 20. Juli 2010 Hallo Bubble, hallo flashpixx, danke für eure Antworten. Kompiliert wird mit g++ (GCC) 4.1.1 mit den folgenden Optionen: CC = g++ -g -ansi -Wall -pedantic -pg. Bezüglich sifeof liefert ja nur die Größe eines Datentyps zurück, das ist ja ja unter 32 oder 64 Bit Systemen erst mal egal, sofern man es korrekt macht. Das ist leider mein Problem. Ich weiß nicht ob es korrekt gemacht worden ist. Die Internetseite die genannt worden ist, ist genau die, von der ich die Idee mit sizeof() habe. Leider komme ich nicht weiter zurecht. Im ersten Beitrag habe ich nicht erwähnt, wo der Code aussteigt, da ich dachte, der Fehler wird schon weiter oben produziert, aber das Programm rettet sich ein wenig weiter. Vielleicht erkennen eure geschulten Augen aber doch, worin der Fehler hochwahrscheinlich liegt. #include <stdio.h> #include <stdlib.h> #include <netcdf.h> #include "main.h" #include "error.h" extern "C" { #include "tri_netcdf.h" #include "tri_netcdf_p.h" #include "tripdat_netcdf.h" #include "netcdf_info.h" } #include "mmemory.h" #include "tri_io.h" #define NO_HISTBYTES_PER_TRI "histbytes_per_tri" #define HIST_STACK "history_stack" #define HIST_LEN "history_depth" #define HIST_STAT "history_status" /******************************************************************************* * Description: *******************************************************************************/ void read_triangulation(char *name){ int i, j, n, npoints, ntriangles; int cdfid, tri_points_var, tri_neighbours_var, points_xc_var, points_yc_var; int points_bdry_var, hist_bytes = 0, bsize; int hist_bytes_var=0, hist_depth_var=0, hist_stat_var=0; Point *pt, **pt_ptr; Triangle *tri, **tri_ptr; NetcdfInfo info; void *buffer; long (*three_long_buf)[3]; double *double_buf; unsigned char *byte_buf; short *short_buf; long *long_buf; if(!nctri_open_tri_file(name, global_parameter.tri_name, &i, &ntriangles, &npoints, &cdfid, &tri_points_var, &tri_neighbours_var, &points_xc_var, &points_yc_var, &points_bdry_var, &info)){ fprintf(stderr, "ERROR:\nCannot open netCDF file\n'%s'!\nWrong type?", name); exit(EXIT_FAILURE); } if((i = netcdf_dim_no(&info, NO_HISTBYTES_PER_TRI)) >= 0){ hist_bytes = (int)info.dim[i].size; if(hist_bytes > HIST_CHARS) fatal_error("Triangulation needs larger history stack than supported!"); } if(hist_bytes){ if((hist_bytes_var = netcdf_var_no(&info, HIST_STACK)) < 0) fatal_error("Missing variable with name " HIST_STACK); if((hist_depth_var = netcdf_var_no(&info, HIST_LEN)) < 0) fatal_error("Missing variable with name " HIST_LEN); if((hist_stat_var = netcdf_var_no(&info, HIST_STAT)) < 0) fatal_error("Missing variable with name " HIST_STAT); } triangulation.ntriangles = ntriangles; triangulation.npoints = npoints; triangulation.triangle = NULL; triangulation.point = NULL; bsize = hist_bytes * triangulation.ntriangles * (int)sizeof(unsigned char); if(3 * triangulation.ntriangles * (int)sizeof(long) > bsize) bsize = 3 * triangulation.ntriangles * (int)sizeof(long); if(triangulation.npoints * (int)sizeof(double) > bsize) bsize = triangulation.npoints * (int)sizeof(double); if((buffer = malloc(bsize)) == NULL) fatal_error("Out of memory!"); if((pt_ptr = (Point **)malloc(npoints * sizeof(*pt_ptr))) == NULL) fatal_error("Out of memory!"); for(i = 0; i < npoints; i++){ pt = alloc_point(); pt->succ = triangulation.point; triangulation.point = pt; } for(i = 0, pt = triangulation.point; i < npoints; i++, pt = pt->succ) pt_ptr[i] = pt; if((tri_ptr = (Triangle **)malloc(ntriangles * sizeof *tri_ptr)) == NULL) fatal_error("Out of memory!"); for(i = 0; i < ntriangles; i++){ tri = alloc_triangle(); tri->succ = triangulation.triangle; triangulation.triangle = tri; } for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ) tri_ptr[i] = tri; if(hist_bytes){ long start[2] = {0, 0}, count[2]; int max_hist = 0; byte_buf = (unsigned char *)buffer; count[0] = ntriangles; count[1] = hist_bytes; ncvarget(cdfid, hist_bytes_var, start, count, buffer); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ){ for(j = 0; j < hist_bytes; j++) tri->hist.hist[j] = byte_buf[hist_bytes * i + j]; } ncvarget(cdfid, hist_stat_var, start, count, buffer); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ){ tri->hist.green = byte_buf[i] & 1; tri->hist.green_ngb = (byte_buf[i] >> 1) & 3; } short_buf = (short *)buffer; ncvarget(cdfid, hist_depth_var, start, count, buffer); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ){ tri->hist.depth = short_buf[i]; if(tri->hist.depth > max_hist) max_hist = tri->hist.depth; } printf("Maximum history size in triangulation: %d\n", max_hist); printf("(Maximum possible = %d)\n", HIST_DEPTH); } else{ for(tri = triangulation.triangle; tri != NULL; tri = tri->succ){ tri->hist.depth = 0; tri->hist.green = FALSE; } } long_buf = (long *)buffer; nctri_read_tri_pkt_bdry(cdfid, points_bdry_var, long_buf, 0, npoints); for(i = 0; i < npoints; i++) pt_ptr[i]->bdry = (short)long_buf[i]; double_buf = (double *)buffer; nctri_read_tri_pkt_x_or_y_c(cdfid, points_xc_var, double_buf, 0, npoints); for(i = 0; i < npoints; i++) pt_ptr[i]->x[0] = double_buf[i]; nctri_read_tri_pkt_x_or_y_c(cdfid, points_yc_var, double_buf, 0, npoints); for(i = 0; i < npoints; i++) pt_ptr[i]->x[1] = double_buf[i]; for(n = 0, pt = triangulation.point; pt != NULL; pt = pt->succ) pt->n = n++; for(n = 0, tri = triangulation.triangle; tri != NULL; tri = tri->succ) tri->n = n++; three_long_buf = (long (*)[3])buffer; nctri_read_tri_pts_or_nbs(cdfid, tri_points_var, three_long_buf, 0, ntriangles); /******************************************************************************* Im Fett makierten Teil wird das Programm bereits im Schleifenanfang, also für (i=0) j=0, verlassen und es tritt ein Speicherzugriffsfehler auf. *******************************************************************************/ for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ) for(j = 0; j < 3; j++) [B]tri->pnt[j] = pt_ptr[three_long_buf[i][j]];[/B] // unberührter Teil des Programmes: nctri_read_tri_pts_or_nbs(cdfid, tri_neighbours_var, three_long_buf, 0, ntriangles); for(i = 0, tri = triangulation.triangle; i < ntriangles; i++, tri = tri->succ) for(j = 0; j < 3; j++) tri->ngb[j] = three_long_buf[i][j] < 0 ? NULL : tri_ptr[three_long_buf[i][j]]; free(tri_ptr); free(pt_ptr); free(buffer); ncclose(cdfid); } /*** read_triangulation() ***/ Isla Zitieren
flashpixx Geschrieben 20. Juli 2010 Geschrieben 20. Juli 2010 Das ist leider mein Problem. Ich weiß nicht ob es korrekt gemacht worden ist. Ich möchte jetzt bei diesem Code nicht sagen "daran liegt es", denn ohne mehr über die Programmierung zu wissen, ist es nicht sinnvoll in dem Code Änderungen durchzuführen. Die Meldung besagt nur, dass Du in einem Speicherbereich arbeitest, wo es nicht geht. Du hast in dem Code eine Menge Zeiger, bei denen man sicher prüfen muss, ob sie korrekt adressiert wurden. Das findest Du aber nur mit einem Debugger auf einem 64Bit System heraus, Du musst Dir ebenfalls die Speicherbereiche anschauen, auf die sie verweisen, damit Du den Fehler beheben kannst. Dir wird nichts anderes übrig bleiben, als den Code zu debuggen und eben dann Fehler für Fehler beseitigen. Zitieren
Isla Geschrieben 20. Juli 2010 Autor Geschrieben 20. Juli 2010 Alles klar. Ich versuche mein Glück nun mit einem Debugger. Hoffentlich finde ich den Fehler. Danke vielmals für eure Antworten Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.