Ein Structure Array und Schwierigkeiten mit malloc
-
typedef struct{ double value; int *seqs; } STRUCT1; int findBestSeqs(STRUCT1 **sqr, int AorB){ int i,err=0; double *nBuf; for(i=0;i<5;i++){ sqr[AorB][i]->seqs = malloc(nn[AorB] * sizeof(int)); if (!SeqBuf[i].seqs){ printf("Out of memory: sqr->seqs\n"); err = 1; goto back; } } nBuf = malloc(nn[AorB] * sizeof(double)); if (!nBuf){ printf("Out of memory: nbuf\n"); err = 1; goto back; } back: free(nBuf); return err; } int main(void){ int i,err=0; STRUCT1 SR[2][5]; int nn[2}; ... for(i=0;i<2;i++){ err = findBestSeqs(SR, i); if (err == 1){ printf("error in findBestSeqs\n"); goto back; } } back: return err; }
Hallo,
ich verzweifel ein bisschen an meinem Code. Es sind 2 Probleme, die ich habe.1. Ich habe hier eine Struktur (STRUCT1), die aus einer Sequenz von ints besteht (Sequenz hat verschiedene Längen für 2 Fälle A und
und ein double value, der diese Sequenz bewertet. Ich wollte einen STRUCT1 Array machen, SR[2][5]. Der erste Werte kann 0 oder 1 sein und steht für die zwei Fälle A und B. Der zweite Index ist für den Zugriff auf die 5 besten Sequenzen jedes Falls. Aber ich krieg die Übergabe an findbestSeq nicht hin. Die Funktion soll eben den Array übergeben bekommen und einen int (=0 oder 1), der den Fall angibt. Den int* seqs möchte ich Speicher zu allocaten, aber je nach Fall unterschiedlich viel. Die Längen für Fall A und B sind in nn[2] gespeichert. Das komische ist, beim ersten Durchlauf Aufruf von findbestSeqs geht es, aber beim zweiten Aufruf hängt er sich hier "sqr[AorB][i]->seqs = malloc(... " auf.
2. Ähnliches Problem. Ich brauche einen Buffer, der bei den beiden Aufrufen von findbestSeq unterschiedliche Längen hat. Beim ersten Mal klappt malloc. Beim zweiten Aufruf, klappt malloc nicht, obwohl ich doch mit free(nBuf) abgeschlossen hab.
Gruß
-
Das ist alles Schrott und obendrein unkompilierbar. Etwas mehr Sorgfalt bei deinem Zusammensuchen der Codeteile, so wird das jedenfalls nichts.
Ein Array ist kein Zeiger, somit stimmt auch nicht immer ** <-> [][].
-
Bei
STRUCT1 SR[2][5]
ist SR nicht gleichbedeutend mit**STRUCT1
!Mach
int findBestSeqs(STRUCT1 sqr[][5], int AorB);
dann weiß der Compiler was du brauchst.
---------------
IHHH goto's
~
sorry musste sein :D~
-
Danke Dirk, deine Idee hat mir n bisschen weitergeholfen. So wie unten läuft das jetzt.
typedef struct{ double value; double *seqs; } STRUCT1; int findBestSeqs(STRUCT1 sqr[], int AorB){ int i,err=0; double *nBuf; for(i=0;i<5;i++){ (&sqr[i])->seqs = malloc(nn[AorB] * sizeof(int)); if (!(&sqr[i])->seqs){ printf("Out of memory: sqr->seqs\n"); err = 1; goto back; } } nBuf = malloc(nn[AorB] * sizeof(double)); if (!nBuf){ printf("Out of memory: nbuf\n"); err = 1; goto back; } back: free(nBuf); return err; } int main(void){ int i,err=0; STRUCT1 SR[2][5]; int nn[2}; ... for(i=0;i<2;i++){ err = findBestSeqs(SR[i], i); if (err == 1){ printf("error in findBestSeqs\n"); goto back; } } back: return err; }
Das mit dem ** kam mir auch spanisch vor, aber ich habe ewig rumprobiert und dann den letzten Stand hier reinkopiert. Das ärgerliche ist, dass ich die Lösung so eigentlich vor ner Weile fast hatte, wusste nur nicht dass bei (&sqr[i])->seqs die runden Klammern notwendig sind.
Hat jemand noch ne Idee zu meiner zweiten Frage? Wie gesagt, nBuf wird in findbestSeq deklariert, "gemalloct" und "gefreet", aber wenn findbestSeq zum 2. Mal aufgerufen wird, geht das nicht mehr.
@Wutz
Hast ja schon gemerkt, dass ich meinen Code nicht selber schreibe sondern einfach Bausteine zusammenklebe. Jetzt habe ich da was gefunden, es sieht echt praktisch aus, aber ich werd nicht ganz schlau draus. Du scheinst ja ein Profi zu sein. Vielleicht kannst du mir weiterhelfen? Es sieht auf jeden Fall schon mal aus wie ein Pointer:___ // 7 (_,_/\ \ \ \ \ _\ \__ ( \ ) \___\___/
Vielen Dank!
-
Das (
&sqr[i])->seqs
ist ja auch großer Quatsch.
Du nimmst die Adresse von sqr[] und dereferenzierst sie dann wieder mit ->
Das ist so als wenn du*(&variable)
schreibst (stattvariable
)
Einsqr[i].seqs
ist doch viel einfacher.Bei
findBestSeqs()
gibst du denn Speicher (den du noch nicht hast) auch im Fehlerfall frei. UndnBuf
zeigt zu dem Zeitpunkt irgendwo hin.Nebenbei hat Wutz mit seinem letzten Satz das gleiche ausgesagt wie ich.
Darfst du so spät überhaupt noch an den Computer?
-
Ja ich hatte Glück, die Pfleger haben sich gestern abend betrunken.
Ich muss trotzdem nochmal nachhaken. Warum lässt man bei
int findBestSeqs(STRUCT1 sqr[][5], int AorB)
die erste eckige Klammer leer? Und wie würde das dann bei der Übergabe ausschauen?
err = findBestSeqs(SR, i);
so?
Danke
-
dephyyar schrieb:
Ja ich hatte Glück, die Pfleger haben sich gestern abend betrunken.
Ich muss trotzdem nochmal nachhaken. Warum lässt man bei
int findBestSeqs(STRUCT1 sqr[][5], int AorB)
die erste eckige Klammer leer?
Weil der Compiler zur Berechnung der Adressen der Elemente innerhalb des Arrays nur die Anzahl der Spalten benötigt. Die Zeilen eines zweidimensionalen Arrays werden nacheinander im Hauptspeicher abgelegt. Um den Beginn einer bestimmten Zeile zu finden, muss also bekannt sein, wie lang eine Zeile ist. Die Anzahl der Zeilen ist dabei aber irrelevant.
dephyyar schrieb:
Und wie würde das dann bei der Übergabe ausschauen?
err = findBestSeqs(SR, i);
so?
Ja.