Übergabe von Array[] -> Structur
-
Hey!
wie übergibt man einen Zeiger(bzw. Array) auf Strukuturen einer Funktion?
Nach stundenlangen Bücherwelzen und &, * etc ausprobieren komme ich keinen Schritt weiter. Der Debugger wirft keinen Fehler allerdings stürzt das Programm ab sobald ich nach der Übergabe der Parameter in der Funktion auf die Werte zugreifen möchte.Ausschnitte des Codes helfen hoffentlich...
struct points { double *coord; }; int main(){ struct points *the_point[100]; //bis zu 100 Strukturen erstellbar the_point[i] = (struct points*) malloc(sizeof(struct points)); the_point[i]->coord = (double*) malloc(sizeof(double)* dimensionen); //Aufruf der Funktion mit übergabe der Adressen auf die unterschiedlichen Strukuturen double ergebnis_distance = distance(dimensionen,punkte,the_point[100]);} int distance(int dimensionen, int punkte, struct points *pn[100]){ }
-
Wie übergibst du denn z.B. char-Arrays (Strings) an strcpy oder printf?
-
Ja nur den ersten Zeiger? Aber das funktioniert in diesem Fall nicht oder ich mach es falsch...
-
Dein Aufruf muss ganz einfach so aussehen:
double ergebnis_distance = distance(dimensionen,punkte,the_point);
Wenn du aber schon mit malloc arbeitest, warum machst du es nicht richtig dynamisch, wieso legst du dich auf die Anzahl von 100 Strukturen fest?
-
CJosef schrieb:
Dein Aufruf muss ganz einfach so aussehen:
double ergebnis_distance = distance(dimensionen,punkte,the_point);
Wenn du aber schon mit malloc arbeitest, warum machst du es nicht richtig dynamisch, wieso legst du dich auf die Anzahl von 100 Strukturen fest?
Das klapp leider nicht, sobald die erste Variable verwendet wird stürzt das Programm ab...
Hier der ganze Code von der Funktion
int distance(int dimensionen, int punkte, struct points *pn[100]){ //für alle Punkte int i=0; int j=0; int i_plus = 1; //nächster Punkt um die Distanz zu berechnen double ergebnis_dimension = 0; double ergebnis = 0; //printf("%lf",pn[1]->coord[1]); //exit(0); while(i <= punkte && i_plus < punkte){ j = 1; while(j <= dimensionen){ //- und + noch beachten falls punkte größer kleiner vorzeichen ändern ergebnis_dimension = ergebnis_dimension + (((pn[i_plus]->coord[j]) - (pn[i]->coord[j])) * ((pn[i_plus]->coord[j]) - (pn[i]->coord[j]))); j++; } ergebnis_dimension = sqrt(ergebnis_dimension); ergebnis = ergebnis + ergebnis_dimension; i++; i_plus++; } return ergebnis; }
Ich hätte das gerne dynamisch gemacht aber ich habe jetzt schon Mühe vor lauter dynamik(Zeiger+Array) den Überblick zu behalten.. Benötige ich dafür die Größe einer Adresse?
struct points *the_point[100];
-> Geht das in die Richtung:
*the_point = (struct *points) malloc(sizeof(Größe_einer_Adresse)*Anzahl_struktur_punkte);
??
-
Dann ist etwas anderes faul, guck dir deine Indizes an.
while(i <= punkte && i_plus < punkte){ // Undefiniertes Verhalten wegen i <= punkte j = 1; // Undefiniertes Verhalten bei dimension = 1 while(j <= dimensionen) // Undefiniertes Verhalten wegen j <= dimensionen
Ein Index beginnt bei 0 und endet bei Anzahl der Elemente - 1.
Die Über-/ Unterschreitung dieser Grenzen kann dein Programm abschmieren lassen.
-
Was mir noch einfällt, deine Struktur besteht hier aus nur einem Member,
da kann man sich die Struktur eigentlich auch sparen.LukeStriker schrieb:
struct points *the_point[100];
-> Geht das in die Richtung:
*the_point = (struct *points) malloc(sizeof(Größe_einer_Adresse)*Anzahl_struktur_punkte);
??Da gibts so einige Möglichkeiten, guckst du:
#include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct tagPoint { double *coord; } point_t; double distance1( point_t** p, int n, int dim ) { int i, j, i1; double dxy = 0; if ( n < 2 ) return 0; for ( i = 0, i1 = 1; i1 < n; i++, i1++ ) for ( j = 0, dxy = 0; j < dim; j++ ) dxy += ( p[i1]->coord[j] - p[i]->coord[j] ) * ( p[i1]->coord[j] - p[i]->coord[j] ); return sqrt ( dxy ); } double distance2( point_t* p, int n, int dim ) { point_t* a, *b; int i, j; double dxy = 0; if ( n < 2 ) return 0; for ( i = 1; i < n; i++ ) for ( a = p + i - 1, b = p + i, dxy = 0, j = 0; j < dim; j++ ) dxy += ( b->coord[j] - a->coord[j] ) * ( b->coord[j] - a->coord[j] ); return sqrt ( dxy ); } double distance3 ( double** p, int n, int dim ) { int i, j, i1; double dxy = 0; if ( n < 2 ) return 0; for ( i = 0, i1 = 1; i1 < n; i++, i1++ ) for ( j = 0, dxy = 0; j < dim; j++ ) dxy += ( p[i1][j] - p[i][j] ) * ( p[i1][j] - p[i][j] ); return sqrt ( dxy ); } double distance4 ( double* p, int n, int dim ) { double* a, *b; int i, j; double dxy = 0; if ( n < 2 ) return 0; for ( i = 1; i < n; i++ ) for ( a = p + (i - 1) * dim, b = p + i * dim, dxy = 0, j = 0; j < dim; j++ ) dxy += ( b[j] - a[j] ) * ( b[j] - a[j] ); return sqrt ( dxy ); } int main(void) { int i; int dim = 3, n = 5; point_t** pta; point_t* ptb; double** ptc; double* ptd; pta = calloc ( n, sizeof ( point_t* )); // Fehlerbehandlung fehlt ptb = calloc ( n, sizeof ( point_t )); // dito ptc = calloc ( n, sizeof ( double* )); // dito ptd = malloc ( n * dim * sizeof ( double )); // dito for ( i = 0; i < n; i++ ) { pta[i] = malloc ( sizeof ( point_t )); // dito pta[i]->coord = malloc ( dim * sizeof ( *pta[i]->coord )); // dito pta[i]->coord[0] = i, pta[i]->coord[1] = i + 1, pta[i]->coord[2] = i + 2; ( ptb + i )->coord = malloc ( dim * sizeof ( *( ptb + i )->coord )); // dito ( ptb + i )->coord[0] = i, ( ptb + i )->coord[1] = i + 1, ( ptb + i )->coord[2] = i + 2; ptc[i] = malloc ( dim * sizeof ( double )); // dito ptc[i] = malloc ( dim * sizeof ( *pta[i]->coord )); // dito ptc[i][0] = i, ptc[i][1] = i + 1, ptc[i][2] = i + 2; (ptd + i * dim)[0] = i, (ptd + i * dim)[1] = i + 1, (ptd + i * dim)[2] = i + 2; } printf ( "%G %G %G %G\n", distance1 ( pta, n, dim ), distance2 ( ptb, n, dim ), distance3 ( ptc, n, dim) , distance4 ( ptd, n, dim )); for ( i = 0; i < n; i++ ) free ( pta[i]->coord ), free ( pta[i] ); for ( i = 0; i < n; i++ ) free (( ptb + i )->coord ); for ( i = 0; i < n; i++ ) free ( ptc[i] ); free ( pta ); free ( ptb ); free ( ptc ); free ( ptd ); getchar(); return 0; }
-
CJosef schrieb:
Dann ist etwas anderes faul, guck dir deine Indizes an.
while(i <= punkte && i_plus < punkte){ // Undefiniertes Verhalten wegen i <= punkte j = 1; // Undefiniertes Verhalten bei dimension = 1 while(j <= dimensionen) // Undefiniertes Verhalten wegen j <= dimensionen
Ein Index beginnt bei 0 und endet bei Anzahl der Elemente - 1.
Die Über-/ Unterschreitung dieser Grenzen kann dein Programm abschmieren lassen.OMG - so einen Fehler hatte ich irgendwie gar nicht auf der Rechnung
Ich hatte des gemacht wegen:printf("Geben Sie die %d.Koordinate des %d.Punkts ein:\n",j,i);
Da hier das mit 0.koord und 0.Punkt blöd anhört. Manchmal kostet einem Faulheit Kopf und Kragen^^ Aber jetzt läuft das Teil!
Das mit dem einem Member der Struktur weiß ich, dass ist so vorgegeben da dieses Prog noch erweitert wird..
Ich entscheide mich für ptb, Zeiger auf Zeiger sehe ich noch etwas kritisch und diese Variante scheint mir ziemlich plausibel. Trotzdem noch ein paar Fragen zum Verständnis:
Struktur:
typedef/my_point
-> Zugriff auf die Strutkur über my_point
Main:
my_point* ptb;
-> Es wird eine Struktur ptb angelegtptb = calloc ( punkte, sizeof ( point_t )); //-- Anzahl der Punkte
-> Wieso verwendest du in deinem Beispiel einmal calloc und dann wieder malloc? Ich dachte der einzige Unterschied liegt in der Initialisierung (mit/ohne 0)?( ptb + i )->coord = malloc ( dim * sizeof ( *( ptb + i )->coord )); // dito
-> ptb +i hab ich noch nie gesehen. Ich denke mal hier wird auf ein Array zurückgegriffen?( ptb + i )->coord[0] = i, ( ptb + i )->coord[1] = i + 1, ( ptb + i )->coord[2] = i + 2;
-> Ich glaube an dem Punkt hast du mein Programm missinterpretiert. Hier habe ich eine andere zuweisung, siehe QuellcodeBitte einfach verbessern wen ich einen Punkt falsch interpretiert habe. Hier noch meine alte main:
int main(){ //Variablenbelegung //Dimension int i = 0; int dimensionen = 0; //Points int j = 0; //count int punkte = 0; //my_point* ptb; struct points *the_point[100]; printf("Geben sie die Anzahl der Dimensionen ein: "); scanf("%d",&dimensionen); printf("Geben sie die Anzahl der Punkte ein: "); scanf("%d",&punkte); //ptb = calloc ( punkte, sizeof ( point_t )); while(i < punkte){ //Variables Array anlegen für Punkte the_point[i] = (struct points*) malloc(sizeof(struct points)); //dyna. Anzahl Dimensionen the_point[i]->coord = (double*) malloc(sizeof(double)* dimensionen); j = 0; while(j < dimensionen){ printf("Geben Sie die %d.Koordinate des %d.Punkts ein:\n",j,i); scanf("%lf",&the_point[i]->coord[j]); j++; } i++; } double ergebnis_distance = distance(dimensionen,punkte,the_point); printf("Die Distanz zwischen den Punkten beträgt: %lf LE",ergebnis_distance); }
-
Ich habe es viel einfacher gelöst, einfach nur
struct points *the_point[dimensionen]; //legt genausoviel Speicheradressplätze an wie benötigt.
Danke nochmal
-
Okay.
LukeStriker schrieb:
ptb = calloc ( punkte, sizeof ( point_t )); //-- Anzahl der Punkte
-> Wieso verwendest du in deinem Beispiel einmal calloc und dann wieder malloc? Ich dachte der einzige Unterschied liegt in der Initialisierung (mit/ohne 0)?Stimmt, fürs Beispiel ist das Wurscht, calloc kann für Aufräumarbeiten nützlich sein, weil dann nicht initialisierte Zeiger entschärft sind und ein free nichts böses tut, wenn man es mit ihnen füttert.
LukeStriker schrieb:
( ptb + i )->coord = malloc ( dim * sizeof ( *( ptb + i )->coord )); // dito
-> ptb +i hab ich noch nie gesehen. Ich denke mal hier wird auf ein Array zurückgegriffen?Das ist die Zeigerschreibweise, ich benutze eigentlich immer die Indexschreibweise, beim Schreiben hatte ich ein bisschen rumgespielt und dann
vergessen zu ändern.LukeStriker schrieb:
( ptb + i )->coord[0] = i, ( ptb + i )->coord[1] = i + 1, ( ptb + i )->coord[2] = i + 2;
-> Ich glaube an dem Punkt hast du mein Programm missinterpretiert. Hier habe ich eine andere zuweisung, siehe QuellcodeIch habe eigentlich nüschts interpretiert :p , sondern ich wollte einfach nur ein paar Werte haben, um die Funktionen zu testen.