Malloc-Problem
-
also das mit dem printf("%12s", ... ) hab ich mir auch schon überlegt, aber dann ist das alles rechtbündig. geht das auch linksbündig? und mein malloc problem ist dann auch noch net gelöst...
-
man: printf(3) - das solltest du dir mal durchlesen, wenn du dich intensiver mit der Ausgabe beschäftigen willst (insbesondere die Auflistung, was dort alles an Format-Ergänzungen kommen kann: "%-12s" druckt z.B. 12 Zeichen linksbündig aus.
@mata: Da siehst du mal, womit ich eher programmiere
-
danke danke danke
... ich glaub ich kriegs jetzt hin mein text zu formatieren... damit wäre aber mein problem mit dem dynamischen array noch net gelöst ...
-
Zeig doch mal her, wie dein bisheriger Ansatz aussieht - und an welcher Stelle du Probleme hast.
Mit malloc müßte das ungefähr so aussehen:
int size=...; struct S_Buch* buchdat=malloc(size*sizeof(struct S_Buch)); //arbeite mit buchdat ganz normal //Array nachträglich vergrößern: size+=delta; buchdat=realloc(buchdat,size*sizeof(struct S_Buch)); //ganz wichtig: Am Ende Speicherplatz freigeben: free(buchdat);
(und du solltest bei jedem *alloc überprüfen, ob er erfolgreich war: "if(buchdat==NULL) Fehlerbehandlung;")
-
Also vielleicht isses einfacher, wenn du das ganze übel siehst
. Ich hab aber unnötige zusatzfunktionen erstmal rausgelassen.
#include <stdafx.h> #include <stdio.h> #include <string.h> #include <conio.h> //*******Struktur**********// struct S_buch { char autor[20]; char titel[40]; char verlag[15]; char kategorie[12]; unsigned int isbnnr; float preis; }; struct S_buch buchdat[500]; //*********MAIN************// int main(void) { int size=1, delta; printf("Geben Sie ein, wieviele Eingaben Sie machen wollen:") scanf("%d", &delta); struct S_Buch* buchdat=malloc(size*sizeof(struct S_Buch)); //arbeite mit buchdat ganz normal //Array nachträglich vergrößern: size+=delta; buchdat=realloc(buchdat,size*sizeof(struct S_Buch)); //ganz wichtig: Am Ende Speicherplatz freigeben: free(buchdat); eingabe(); _getch(); } //********Eingabe**********// void eingabe() { int i=0, weiter, yes; size_t lng; while(true) { printf("Bitte machen Sie ihre %d. Eingabe:\n", i+1); printf("Autor:\t\t"); gets(&buchdat[i].autor[0]); {lng = strlen(buchdat[i].autor);if(lng>20){printf("Der Autor war zu lang, bitte max. 20 Zeichen verwenden"); continue;}} printf("Titel:\t\t"); gets(&buchdat[i].titel[0]); {lng = strlen(buchdat[i].titel);if(lng>40){printf("Der Titel war zu lang, bitte max. 40 Zeichen verwenden"); continue;}} printf("Verlag:\t\t"); gets(&buchdat[i].verlag[0]); {lng = strlen(buchdat[i].verlag);if(lng>15){printf("Der Verlag war zu lang, bitte max. 15 Zeichen verwenden"); continue;}} printf("Kategorie:\t"); gets(&buchdat[i].kategorie[0]); {lng = strlen(buchdat[i].kategorie);if(lng>12){printf("Die Kategorie war zu lang, bitte max. 12 Zeichen verwenden"); continue;}} printf("ISBN-Nr:\t"); scanf("%d", &buchdat[i].isbnnr); {lng = strlen(buchdat[i].autor);if(lng>15){printf("Die ISBN-Nr. war zu lang, bitte max. 15Zeichen und keine Bindestriche verwenden"); continue;}} printf("Preis:\t\t"); scanf("%f", &buchdat[i].preis); printf("\nNeuen Datensatz eingeben? 1(Ja) oder 0(Nein)\n"); scanf("%d", &weiter); if(weiter==1) { i = i+1; } else { break; } }
Ich hab das jetzt mal in die main eingefügt, was du gesagt hast, aber klappt net... isch raffs irgendwie net ...
was gibt mir denn malloc und relloc eigentlich zurück?
-
Das hier
struct S_buch buchdat[500];
kollidiert mit
int main() { //... struct S_Buch* buchdat=malloc(size*sizeof(struct S_Buch)); //Array nachträglich vergrößern: size+=delta; buchdat=realloc(buchdat,size*sizeof(struct S_Buch)); //... }
Btw. Für was legst du buchdat in der main an? Du benutzt es eh nicht bzw. löschst es bevor die eingabe - Funktion damit arbeiten könnte.
-
Das wird nichts, wenn du alles hintereinander wegschreibst. malloc() rufst du einmal am Anfang des Programms auf, free() einmal am Ende (unmittelbar bevor du das Programm verläßt) und realloc() zwischendurch, wenn dein Platz nicht mehr reicht:
struct S_Buch{...} struct S_Buch* buchdat;//OK, globale Variablen sind grausam void eingabe(int* platz) { int i=0, weiter, yes; size_t lng; while(true) { if(i>=*platz)//Array voll->vergrößern { (*platz)+=10; buchdat=realloc(buchdat,size*sizeof(struct S_Buch)); } printf("Bitte machen Sie ihre %d. Eingabe:\n", i+1); // Eingaben printf("\nNeuen Datensatz eingeben? 1(Ja) oder 0(Nein)\n"); scanf("%d", &weiter); if(weiter==1) i = i+1; else break; } } int main(void); { int size, delta; printf("Geben Sie ein, wieviele Eingaben Sie machen wollen:") scanf("%d", &size); buchdat=malloc(size*sizeof(struct S_Buch)); //arbeite mit buchdat ganz normal eingabe(&size);//<- hier würde ich eventuell noch die Größe des Arrays mitgeben //... //ganz wichtig: Am Ende Speicherplatz freigeben: free(buchdat); _getch(); return 0; }
-
cool ... danke, ich glaub jetzt versteh ichs mehr oder weniger...
was ich noch nicht verstehe ist:
if(i>=*platz)//Array voll->vergrößern { (*platz)+=10; buchdat=realloc(buchdat,size*sizeof(struct S_Buch)); }
warum machst du das? ich hab doch schon in der main ne abfrage gemacht, wieviele daten der user eingeben möchte, warum machst du dann (*platz)+=10 ? oder muss ich in der struktur buchdat[500] umändern in buchdat[1] oder so?
Ach und beim compilieren kommen folgende Fehler, wenn ich einfach alles so benutze:
(38) : error C2027: Verwendung des undefinierten Typs "(void)main::S_Buch"
(38): Siehe Deklaration von '(void)main::S_Buch'
(38) : error C2440: '=': 'void *' kann nicht in 'S_buch [500]' konvertiert werden
Es gibt keine Konvertierungen von Arraytypen, obwohl es Konvertierungen von Verweisen oder Zeigern in Arrays gibt
(41) : error C2660: 'eingabe': Funktion akzeptiert keine 1 Argumente
(60) : error C2065: 'size': nichtdeklarierter Bezeichner
(60) : error C2027: Verwendung des undefinierten Typs "(int *)eingabe::S_Buch"
(60) : Siehe Deklaration von '(int *)eingabe::S_Buch'
-
Nein, du mußt das Array "struct S_Buch buchdat[500];" ändern in einen Pointer "struct S_Buch* buchdat;" - Arrays haben eine feste Größe und festgelegten Speicher, also ist dafür das ganze malloc()/realloc()/free() unnötig.
(und die angegebene if()-Abfrage ist für den Fall, daß der User mehr Daten eingibt als er angekündigt hat)
-
also ich dachte ich hätte es gerafft, aber mein pc meinte da wohl was anderes.
hier mein code:#include <stdafx.h> #include <stdio.h> #include <string.h> #include <conio.h> //*******Struktur**********// struct S_buch { char autor[20]; char titel[40]; char verlag[15]; char kategorie[12]; unsigned int isbnnr; float preis; }; struct S_buch *buchdat; //***Funktionen benennen***// void eingabe(); void ausgabe(struct S_buch *buchdat, int test); void sortieren_autor(struct S_buch *feld, int laenge); void sortieren_titel(struct S_buch *feld, int laenge); void waechseln(struct S_buch *k, struct S_buch *l); //void suchen(struct S_buch *buchdat, int lv); //*********MAIN************// int main(void) { int size; printf("Geben Sie ein, wieviele Eingaben Sie machen wollen:"); scanf("%d", &size); buchdat=malloc(size*sizeof(struct S_Buch)); //arbeite mit buchdat ganz normal eingabe(&size);//<- hier würde ich eventuell noch die Größe des Arrays mitgeben //... //ganz wichtig: Am Ende Speicherplatz freigeben: free(buchdat); _getch(); return 0; } //********Eingabe**********// void eingabe(int *platz) { int i=0, weiter, yes; size_t lng; while(true) { if(i>=*platz)//nur vorsorge, falls user doch mehr eingabe tätigen will, als er angekündigt hat { (*platz)+=10; buchdat=realloc(buchdat,platz*sizeof(struct S_Buch)); } printf("Bitte machen Sie ihre %d. Eingabe:\n", i+1); printf("Autor:\t\t"); gets(&buchdat[i].autor[0]); {lng = strlen(buchdat[i].autor);if(lng>20){printf("Der Autor war zu lang, bitte max. 20 Zeichen verwenden"); continue;}} printf("Titel:\t\t"); gets(&buchdat[i].titel[0]); {lng = strlen(buchdat[i].titel);if(lng>40){printf("Der Titel war zu lang, bitte max. 40 Zeichen verwenden"); continue;}} printf("Verlag:\t\t"); gets(&buchdat[i].verlag[0]); {lng = strlen(buchdat[i].verlag);if(lng>15){printf("Der Verlag war zu lang, bitte max. 15 Zeichen verwenden"); continue;}} printf("Kategorie:\t"); gets(&buchdat[i].kategorie[0]); {lng = strlen(buchdat[i].kategorie);if(lng>12){printf("Die Kategorie war zu lang, bitte max. 12 Zeichen verwenden"); continue;}} printf("ISBN-Nr:\t"); scanf("%d", &buchdat[i].isbnnr); {lng = strlen(buchdat[i].autor);if(lng>15){printf("Die ISBN-Nr. war zu lang, bitte max. 15Zeichen und keine Bindestriche verwenden"); continue;}} printf("Preis:\t\t"); scanf("%f", &buchdat[i].preis); //{lng = strlen(buchdat[i].autor);if(lng>6){printf("Der Preis war zu lang, bitte max. 6Zeichen verwenden"); continue;}} printf("\nNeuen Datensatz eingeben? 1(Ja) oder 0(Nein)\n"); scanf("%d", &weiter); if(weiter==1) { i = i+1; } else { break; } } printf("Möchten Sie die Liste sortieren? 1 (Ja), 0 (Nein)\n"); scanf("%d", &yes); if(yes==1) { printf("Nach was? 1 (Autor), 2 (Titel)\n"); scanf("%d",&yes); if(yes==1) { sortieren_autor(buchdat, i); } else { sortieren_titel(buchdat, i); } } ausgabe(buchdat, i); //suchen(buchdat, i); } //******************Ausgabe*************************// void ausgabe(struct S_buch *buchdat, int test) { char a[6]="Autor", b[6]="Titel", c[7]="Verlag", d[9]="ISBN-Nr.", e[6]="Preis", f[10]="Kategorie"; printf("\n%-20s\t", a); printf("%-30s\t", b); printf("%-15s\t\t", c); printf("%-15s\t\t", d); printf("%-10s\t", e); printf("%-12s", f); printf("\n\n"); for(int u=0;u<=test;u++) { printf("%-20s/\t", buchdat[u].autor); printf("%-30s/\t", buchdat[u].titel); printf("%-15s/\t", buchdat[u].verlag); printf("%-15d/\t", buchdat[u].isbnnr); printf("%-10.2f/\t", buchdat[u].preis); printf("%-12s", buchdat[u].kategorie); printf("\n"); } } //******************Sortieren***********************// void sortieren_autor(struct S_buch *feld, int laenge) { for (int los=0; los < laenge; ++los) { int min_index=los; for (int j=los; j<laenge+1; ++j) { int stimmt = strcmp(feld[j].autor, feld[min_index].autor); if (stimmt<0) { min_index=j; } } waechseln(&feld[los], &feld[min_index]); } } void sortieren_titel(struct S_buch *feld, int laenge) { for (int los=0; los < laenge; ++los) { int min_index=los; for (int j=los; j<laenge+1; ++j) { int stimmt = strcmp(feld[j].titel, feld[min_index].titel); if (stimmt<0) { min_index=j; } } waechseln(&feld[los], &feld[min_index]); } } //*****************Tauschen***********************// void waechseln(struct S_buch *k, struct S_buch *l) { struct S_buch temp = *k; *k=*l; *l=temp; }
wenn ich das durch den compiler jage, dann gibt er mir folgende fehlermeldungen:
error C2027: Verwendung des undefinierten Typs "(void)main::S_Buch"
Siehe Deklaration von '(void)main::S_Buch'
error C2440: '=': 'void *' kann nicht in 'S_buch ' konvertiert werden
Konvertierung von 'void' in Zeiger auf nicht-'void' erfordert eine explizite Typumwandlung
error C2660: 'eingabe': Funktion akzeptiert keine 1 Argumente
error C2027: Verwendung des undefinierten Typs "(int *)eingabe::S_Buch"
Siehe Deklaration von '(int )eingabe::S_Buch'
error C2296: '': Ungültig, da der linke Operand vom Typ 'int *' istich komm einfach net drauf klar.
-
Hallo Jarlaxle,
du hast in diversen Zeilen einfach
S_Buch
statt
S_buch
geschrieben.
Ausserdem musste ich bei mir noch die
#include <stdlib.h>
einbinden. Wegen malloc und realloc
Und ich würde bei malloc und realloc entsprechend casten
buchdat=(S_buch*)malloc(size*sizeof(struct S_buch));
Nur ein paar Tipps...
Gruss
Tobi[edit]
Ach ja, fast hätte ich es vergessen...
Der Protoyp von deiner Eingabefunktion stimmt nicht mit der Implementierung übereineingabe();
passt nicht zu
eingabe(int* zahl)
und der Zeiger wird beim realloc nicht richtig verwendet
buchdat=(S_buch*)realloc(buchdat,(*platz)*sizeof(struct S_buch));
[/edit]
Gutes neues allerseits...
-
yeah, es funktioniert alles ... vielen vielen herzlichen dank...