Bitte nach ANSI-C verschieben: Speicherzugriffsfehler auf 64-Bit Architektur



  • Hallo,

    ich habe leider ein etwas schwierigeres Problem, deshalb versuche ich das Ganze möglichst genau und trotzem knapp zu schildern.
    Ich soll für ein recht umfangreiches Programm Programmteile schreiben, und Fehler beheben.

    Das Programm funktioniert auf 32-Bit Architekturen wunderbar, auf 64-Bit Rechnern kommt es zu einem Speicherzugriffsfehler. Da weder ich, noch meine Kollegen Informatiker sind, sind wir mit dem Problem etwas überfordert.

    Der Programmteil, in dem der Fehler auftritt, liest eine Triangulierung ein. Die Triangulierung besteht eigentlich nur aus Punkten, deren Koordinaten, und deren Nachbarpunkten und Dreiecken, welche durch die Punktkoordinaten definiert sind. Das kleinste Versuchsbeispiel, das möglich ist, besteht aus 4 Punkten, im Code npoints, und drei Dreiecken, im Code ntriangles. Hiefür wird im Programm mit malloc Speicher bereitgestellt, und die Punkte abgespeichert. Allerdings wird oft Speicher für verschiedene Variablentypen benutzt, mit Zeigern und Adressen rumgespielt, wo ich ehrlich gesagt einfach nicht durchblicke. Deshalb will ich auch keine komplett kommentierte Version reinstellen, da ich nicht falsch kommentieren will.

    Meine Vermutung ist, da ja oft sizeof verwendet wird, und die Datentypen, z.b. long zum Teil verschiedene Größen auf den verschiedenen Architekturen haben, hier ein Fehler auftritt.

    Das Programm bricht erst ziemlich zum Schluss in Zeile 110, in der vorletzten For-Schleife, schon im ersten Durchgang ab. Und zwar kann es nicht auf pt_ptr[three_long_buf[i][j]] zugreifen.

    Hier die so gut wie möglich abgespeckte Version:

    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;
    
      hist_bytes = 0     /*Eigentlich anders ermittelt, im Versuchsbeispiel jedoch 0*/
    
      triangulation.ntriangles = ntriangles;    /*im Versuchsbeispiel 3*/
      triangulation.npoints = npoints;          /*im Versuchsbeispiel 4*/
      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();
        cout << "triangulation.point " << triangulation.point << endl;
        pt->succ = triangulation.point;
        triangulation.point = pt;
      }
    
      for(i = 0, pt = triangulation.point; i < npoints; i++, pt = pt->succ){
         cout << "pt" << pt << endl;  
         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;
    
      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]]; /*Hier tritt der Speicherzugriffsfehler auf.*/
        }
    
      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() ***/
    

    Vielen Dank im Voraus schon mal. Ich hoffe, jemand von euch hat eine Idee.

    Liebe Grüße, Elina



  • Wo genau wird eigentlich "Buffer" angelegt. Definiert ist es ja als Pointer auf void.



  • pt_ptr wird ja übergeben. Habt Ihr schon mal geschaut, ob der Speicher sauber per Malloc geholt wurde? Ist der code auch für 64 bit übersetzt worden?



  • Hab es gefunden...

    Der Code ist prinzipiell Ansi-C und gehört daher auch in die entsprechende Rubrik.
    Desweiteren wäre der Code leichter zu lesen, wenn er mit den entsprechenden Tags formatiert wäre.



  • Ok, danke schon mal. Ich versuch, das Ganze ordentlicher zu machen und stells noch mal in den C- Teil rein. 🙂
    Oder kann jemand vielleicht den ganzen Thread verschieben?

    Übersetzen für 64 Bit geht ohne Probleme, nur eben das Ausführen nicht.
    pt_ptr wird übergeben, das stimmt. Ich habe halt getestet, ob ich das ausgeben kann. Und da bekomm ich den Speicherzugriffsfehler.


Anmelden zum Antworten