Zum Inhalt springen

Umstellung eines 32-bit Programms auf 64-bit


Isla

Empfohlene Beiträge

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() ***/




Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...