Dynamische Größe von Arrays
-
bladepit schrieb:
Nochmal: das funktioniert alles.
Der 'funktionierende' Code ist eine einzige memory-leak-factory.
bladepit schrieb:
Können wir denn nicht über die Lösung meines Problems reden?
Das ist das Ziel.
Ich wollte dir zeigen, wie man auf einfache Weise Code optimieren und unnötige Allokation vermeiden kann.
-
bladepit schrieb:
Nochmal: das funktioniert alles. Können wir denn nicht über die Lösung meines Problems reden?
Ja was denn nun?
Funktioniert alles, dann hast du kein Problem.int main(int argc, char **argv){ char buf[BUFSIZ]; short a = 0; short b = 0; short anzc=0; short anzd=0; char (*c)[BUFSIZ]; /* das hier war falsch, jetzt ist es korrekt ein Zeiger d.h. also quasi eine Liste auf String mit max. BUFSIZ-1 Länge */ short *d; short i; while (fgets(buf, BUFSIZ, stdin) != NULL) { if (buf[strlen(buf)-1] == '\n') { char *isa = strstr(buf, "A:")==buf; char *isb = strstr(buf, "B:")==buf; char *isc = strstr(buf, "C:")==buf; char *isd = strstr(buf, "D:")==buf; if(isa){ char *sep = buf+2; a = atoi(sep); d = malloc(a*sizeof(short)); }else if(isb){ char *sep = buf+2; b = atoi(sep); c = calloc(b,BUFSIZ); /* hier natürlich einen Speicherbereich definieren und anschließend als Stringliste gebrauchen! */ }else if(isc){ char *sep = buf+2; strcpy(c[anzc],sep); /* und hier natürlich keine einfache Zuweisung, sondern strcpy */ anzc++; }else if(isd){ char *sep = buf+2; d[anzd] = atoi(sep); anzd++; } } } printf("%i\n", anzc); printf("%i\n", anzd); for(i=0; i<anzc;i++){ printf("%s",c[i]); /* hier dann natürlich Strings ausgeben mit %s und nicht Zeichen %c wie du */ } return 0; }
-
Ok damit hast du mir geholfen. Ich bin immer für Optimierungen versteht mich da nicht falsch nur wollte ich das Programm erstmal zum laufen bringen.
Jetzt habe ich noch eine Frage. Wie muss ich ein Array anlegen und dann auch automatische vergrößern das folgende Eingaben beinhalten soll:
0 0 44
0 1 33
1 0 55
1 1 66Die ersten 2 Zahlen in jeder Reihe ist der Index. Die erste Spalte hat die Anzahl b und die zweite Spalte die Anzahl a.
Mir ist da nicht klar welche Typ das Array haben müsste und wie ich das dann entsprechend wenn ich die Größen von der STDIN gelesen habe auch vergrößere.
-
Ich habe nicht verstanden, was du erreichen willst und was diese Aufgabenstellung mit der vorigen gemeinsam hat.
-
Es kommen noch Werte ich halten muss. Zum einen brauch die alle Bezeichner das war quasi die vorherige Aufgabe und nun noch die Werte.
Dabei ist die dritte Spalte die Werte Spalte.
-
@Wutz: Speicherfreigabe fehlt!
bladepit schrieb:
Ok womit ich dann noch ein Problem habe:
Kann ich diese Datenstrukturen dann erst erstellen wenn ich A und B gelesen habe?
Ich komme aus der Java-Welt da würde ich halt ein c = new char[b] machen...
dir ist klar, dass du in c die speicherverwaltung selbst in der hand hast, da es keinen garbage collector gibt?
bladepit schrieb:
ich sage direkt das ich totaler Neuling in C bin und daher noch so arge Probleme habe. Nun meine Fragestellung. Über die STDIN kriege ich verschiedene Zeilen geliefert die ich auslesen will:
A:2
B:3
C:ADWD
C:ADAFWF
C:WDAWD
D:200
D:100Diese will ich auslesen und mir in C dann merken. A ist die Anzahl der D-Werte und B die Anzahl der C-Werte.
dir ist klar, dass du, wenn die eingaben in der form
A:2
B:3
C:ADWD
C:ADAFWF
C:WDAWD
D:200
D:100
A:3
B:4
C:ADWD
C:ADAFWF
C:WDAWD
C:DWADW
D:200
D:100
D:300sind, ein problem hast?
bladepit schrieb:
Jetzt habe ich noch eine Frage. Wie muss ich ein Array anlegen und dann auch automatische vergrößern das folgende Eingaben beinhalten soll:
0 0 44
0 1 33
1 0 55
1 1 66
Die ersten 2 Zahlen in jeder Reihe ist der Index. Die erste Spalte hat die Anzahl b und die zweite Spalte die Anzahl a.Mir ist da nicht klar welche Typ das Array haben müsste und wie ich das dann entsprechend wenn ich die Größen von der STDIN gelesen habe auch vergrößere.
bladepit schrieb:
Wie muss ich ein Array anlegen
bladepit schrieb:
Die ersten 2 Zahlen in jeder Reihe ist der Index.
wenn es ein index ist, wieso ist dazwischen ein leerzeichen?
wenn es zwei indizes sind, wieso willst du ein array anlegen.dir ist klar, dass mit deiner beschreibung keine sau etwas anfangen kann?
-
Mit der Speicherverwaltung wusste ich nicht.
Heißt am Ende des Programms muss ich free machen?
Mit den Daten das weiß ich. Die kommen immer so wie ich das beschrieben haben.
Ok noch mal zu der neuen Aufgabe:
Es kommen nun Werte (55,44,33,22,11) die ich in einem 2 dimensionalen Array brauche:
arr[0][0] = 55
arr[0][1] = 44
arr[1][0] = 33
usw....Die Länge des Arrays ist dabei bestimmt durch die Werte in a und b. arr[#b][#a].
Jetzt klarer? Ich weiß nicht wie ich das Array anlege und dem nach dem Lesen dann den Platz allokiere.
-
bladepit schrieb:
Mit der Speicherverwaltung wusste ich nicht.
Heißt am Ende des Programms muss ich free machen?wenn der speicher nicht mehr gebraucht wird, sollte er freigegeben werden, richtig.
ein bisschen selbst was nachlesen könntest du auch mal ruhig
-
bladepit schrieb:
Ok noch mal zu der neuen Aufgabe:
Es kommen nun Werte (55,44,33,22,11) die ich in einem 2 dimensionalen Array brauche:
arr[0][0] = 55
arr[0][1] = 44
arr[1][0] = 33
usw....Die Länge des Arrays ist dabei bestimmt durch die Werte in a und b. arr[#b][#a].
Jetzt klarer? Ich weiß nicht wie ich das Array anlege und dem nach dem Lesen dann den Platz allokiere.
na also, geht doch!
int i, j; int m = 20, n = 100; // array[20][100] int** array = malloc ( m * sizeof ( int* )); if ( array == NULL ) return 0; for ( i = 0; i < m; i++ ) { array[i] = malloc ( n * sizeof ( int )); if ( array[i] == NULL ) break; } // Der Speicher fürs Array ist Allokiert, die Elemente lassen sich per Index array[i][j] schreiben/lesen. puts("Allokation abgeschlossen. Druecke enter fuer Speicherfreigabe."); getchar(); // Es folgt die Speicherfreigabe, goldene Regel: für jedes malloc ein free. for ( j = 0; j < i; j++ ) free ( array[j] ); free ( array ); return 0;
-
Danke für deine Hilfe.
Hat alles super geklappt. Jetzt habe ich noch eine Frage. Folgender Code:
short int first[550]; short int second[550]; int i,z,b,ina; double in,val,p; for (i = 0; i<550; i++){ first[i] = (short int) rand() % 20; second[i] = (short int) rand() % 20; } for(i = 0; i <= 17000; i++){ for(z = 0; z < i; z++){ ina=0; val=0; for(b=0; b<sizeof(first);b++){ in = first[b] - second[b]; val+=in*in; ina++; } p = sqrt(val)/(sqrt(ina)*20); } }
Mit der Zeile wo ich sqrt() aufrufe wird das Programm extrem gebremst. Eine Wurzel kann mein Programm doch nicht so bremsen. Ich brauch für die Ausführung exakt 7 Minuten und für ohne die Wurzelberechnung quasi 0 Sekunden. (Ausgaben vor und hinter den For-Schleifen)
-
Doch, eine Wurzel kann dein Programm extrem bremsen.
Vermeide Wurzeln in Schleifen.
-
Naja ich brauch die da schon.
Von der Logik her.
Was haltet ihr von anderen SQRT Methoden:
http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi
-
Ohne mir den Thread jetzt durchzulesen:
Was willst du berechnene?
-
Im Beispiel ist das der Euklid. Genormt per Division aber die kann man auch weglassen dann ist es aber trotzdem noch langsam.