Zum Inhalt springen

Umstellung eines 32-bit Programms auf 64-bit


Empfohlene Beiträge

Geschrieben

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




Geschrieben

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?

Geschrieben

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

Geschrieben

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

  Zitat

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

Geschrieben
  Isla schrieb:

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.

Geschrieben

Alles klar. Ich versuche mein Glück nun mit einem Debugger. Hoffentlich finde ich den Fehler.

Danke vielmals für eure Antworten :)

Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde Dich hier an.

Jetzt anmelden

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.

Weiterlesen  

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...