calloc -- Problem mit Suse 10.0

M

magjo

Grünschnabel
Hi

Problem:
Ich muss ein 2 Dimensionales Feld a[j] je nach Eingabeparameter im laufenden Programm erstellen und anschließend an ein Fortranunterprogramm (pgplot) weitergeben.

eigentlich ganz einfach dachte ich:


Code:
#include <stdio.h>
#include <stdlib.h>

main()
{
int x=512, y=512,i;
float **data;

data = (float**)calloc(x,sizeof(float*));
    for(i=0;i<x;i++) 
      data[i] = (float*)calloc(y,sizeof(float));


printf("\n%lu %lu \n\n",(long)&(data[1][0])-(long)&(data[0][0]),(long)&(data[0][1])-(long)&(data[0][0]));
}

Compiliere ich das Programm mit gcc unter FreeBSD liefert es das korrekte Erbebnis:
Code:
joachim@pythagoras:~/MFM> ./feld

2048 4

mache ich das gleiche mit Suse 10.0 bekomme ich das Ergebnis
Code:
joachim@pythagoras:~/MFM> ./feld

2056 4

wenn ich dieses Feld an die Fortranroutine (pgplot) weitergebe verschiebt sich alles.

ich hab es bei Suse schon mit gcc-3.3.5 versucht gleiches Ergebnis. Ich hab in diesem Fall leider die Vorgabe, dass das Programm unter Suse erstellt werden soll.

Danke
Joachim
 

Anhänge

  • feld.c.txt
    310 Bytes · Aufrufe: 8
Hi!
Also bei mir gibt er auch 2056 4 aus! (slackware)
(Natürlich kann es immer an den Konvertierungen liegen- die solltest du mal einzeln testen), aber eigentlich:

Du gehst ja wahrscheinlich davon aus, dass der Speicherplatz den du reservierst komplett an einem stück ist.. und Subrahierst dann die Adressen.
Ich wüsste aber nicht, dass ein Standard (zB. ansi) festlegt, dass das auch wirklich so sein muss.
Beim jedem calloc aufruf bekommst du deinen Speicherbereich an einem Stück, dazwischen darf doch aber das OS machen was es will, oder?!
Ich will nochmal betonen, dass ich mich da wirklich nicht im Detail auskenne.
Aber ich würde behaupten, dass bei der Reservierung Linux anders vorgeht als dein Freebsd..
 
Hi

das eigentliche Problem dabei ist, dass ein:

Code:
#include <stdio.h>
#include <stdlib.h>

main()
{

float data[512][512];

printf("\n%lu %lu \n\n",(long)&(data[1][0])-(long)&(data[0][0]),(long)&(data[0][1])-(long)&(data[0][0]));
}

bei Suse auch 2048 4 ausgibt und das Fortranunterprogramm von pgplot nur mit dieser Speicherallokierung richtig arbeitet. Sieht richtig Sch.... aus wenn jede Zeile in einem Bild immer um 8 Byte verschoben wird.


Joachim
 
also ist dein Fotran Programm absolut Architektur und OS abhängig ...

kannst du dir die Speicherverteilung nicht evtl. hintricksen? Indem du erstmal den gesamten Speicherplatz reservierst und dort mit Pointerarithmetik arbeitet?
calloc lefert ja void Pointer , die kannst du doch konvertieren wie du willst ...

Wie sieht denn die Übergabe an das Fortran Programm aus ... was erwartet das genau
 
Hi
kannst du dir die Speicherverteilung nicht evtl. hintricksen?
Das versuche ich seit gestern.

Indem du erstmal den gesamten Speicherplatz reservierst und dort mit Pointerarithmetik arbeitet?

ist natürlich schöner (für meine Mitmenschen) wenn man mit data[x][y] arbeitet, anstatt mit *(data+x*xdim+y) oder so ähnlich.

Joachim


/*---------------------------------------------------------------------------*/
Hab die Lösung nicht schön aber selten


#include <stdio.h>
#include <stdlib.h>


main()
{
int x=512, y=512,i;
float **data;

data = (float**)calloc(x,sizeof(float*));
for(i=0;i<x;i++)
data = (float*)(calloc(y,sizeof(float))-(i * 8 ));


printf("\n%lu %lu \n\n",(long)&(data[1][0])-(long)&(data[0][0]),(long)&(data[0][1])-(long)&(data[0][0]));
}




Danke für die Anregung
Joachim
 
Zuletzt bearbeitet:
Also dein Problem liegt ja schon eher beim Fortran Programm, oder?
Vielleicht lohnt es sich, dass etwas allgemeiner zu halten (da kenn ich mich wirklich gar nicht aus :-) )

Ansonsten sind doch die [] Klammern nur ne andere Schreibweise für das *(..+..)

Wenn du also einfach die Bytes alloziierst die du brauchst. dann den Pointer nach float* konvertierst und die ersten 512 Bytes entsprechend auf die richtigen Adressen setzt, solltest du doch alles fertig haben ?

Der Nutzer kann dann einfach über die[] zugreifen ?
Sollte doch gehen ...

das ist Geraten: Alternativ kannst du ja mal nen man gcc versuchen, vielleicht gibt es ja ne Option um ne andere Speicherverwaltung zu erzwingen
 
Danke für die Hilfe

Problem gelöst siehe oben


Joachim
 
Ich denke das lag an dem sizeof(float*), das muss glaube ich sizeof(float) sein...
 
hi

nee (float *) denke ich ist richtig, kannste ja mal mit "double" ausprobieren.

der folgende code sollte besser funktionieren als der oben, da er allgemeingültiger ist


Code:
#include <stdio.h>
#include <stdlib.h>


main()
{
int x=512, y=512,i;
float **data;

data = (float**)calloc(x,sizeof(float*));
data[0]=(float *) calloc (x*y,sizeof(float));
for(i=0;i<x;i++)
   data[i] = (float*)(data[0]+i*y);

printf("\n%lu %lu \n\n",(long)&(data[1][0])-(long)&(data[0][0]),(long)&(data[0][1])-(long)&(data[0][0]));
}

Danke
Joachim
 

Ähnliche Themen

NagiosGrapher 1.7.1 funktioniert nicht

dovecot und postfix Konfiguration Problem

Ubuntu X / dbus problem

Segmentation fault -- warum?

Ausgabe in *.txt Datei & Struct

Zurück
Oben