Probleme mit Speicherallokation
-
Hallo,
ersteinmal schöne Restweihnachten. wir haben folgende Aufgabe gekriegt:Schreiben Sie eine Funktion, die ein Feld mit double-Werten initialisieren soll. Dazu sollen
die Größe des gewünschten Feldes und ein Pointer übergeben werden.
Prototyp: void allocMem(int length, void **ptrptr);
Die Funktion soll per malloc Speicher anfordern, und den Pointer auf den Speicherbereich
auf die uebergebene Variable korrekt speichern. Anschließend soll das Feld per memset (informieren
Sie sich per man–Page über den Befehl) mit Nullen initialisiert werden.
Schreiben Sie ein Hauptprogramm, welches die Funktion aufruft (mit einer vom Benutzer eingegebenen
Länge) und das Feld mit Benutzereingaben füllt. Am Ende des Hauptprogramms
soll natürlich der Speicher wieder freigegeben werden.Bisher sieht unser Programm so aus:
#include <stdio.h> #include <stdlib.h> #include <string.h> void allocMem (int length, void **ptrptr, int f) { double *feld[length]; feld=(double *) malloc(length); memset(*feld, 0 ,length); feld[f]=**ptrptr; } void eingabe (int i, int *wert) { int a; printf("%d. Zahl eingeben", i); scanf("%d", &a); *wert=a; } int main() { int i=1,groesse,*zahl; printf("Geben Sie die gewuenschte Groeße ein"); scanf("%d", &groesse); while(i<groesse) { allocMem(groesse , eingabe(i, &*zahl),i); i++; } return(0); }
Zum einen spuckt er einige Fehler beim kompilieren aus. In der main funktioniert die Übergabe an die allocMem nicht so, wie sie sollte. Er klagt über Probleme, dass er double * übergibt usw...Außerdem steht ja in der Aufgabe dieser Prototyp und da wird ja der Zähler nicht übergeben. meint ihr es ist schlimm, wenn man deren Prototyp ändert?
Vielen Dank schonmal
-
#include <stdio.h> #include <stdlib.h> #include <string.h> // brauchst du nicht void allocMem (int length, void **ptrptr, int f) // Wo kommt das f denn jetzt her? { double *feld[length]; // Weißt du was das ist? Las das [l...] weg und arbeite mit void * feld=(double *) malloc(length); // Überlege mal wie viel Speicher EIN double belegt memset(*feld, 0 ,length); // Hier musst du entsprechen anpassen feld[f]=**ptrptr; // in ptrptr soll die Rückgabe sein: *ptrptr = feld } void eingabe (int i, int *wert) // Warum int?. Du sollst doch double Werte einlesen { int a; printf("%d. Zahl eingeben", i); scanf("%d", &a); *wert=a; } int main() { int i=1,groesse,*zahl; printf("Geben Sie die gewuenschte Groeße ein"); scanf("%d", &groesse); while(i<groesse) { allocMem(groesse , eingabe(i, &*zahl),i); // Geht nicht, denn eingabe gibt keinen Funktionswert zurück. Was ist &*zahl? i++; } return(0); }
Außerdem sollst du ein Feld für double-Werte beschaffen und dann füllen und nicht in einer Schleife Wert holen und dann das Feld.
Du würdest groesse mal ein Feld anfordern.
Nochmal zu &*zahl.
& gibt die Adresse einer Variablen.
* gibt den Inhalt auf den ein Zeiger zeigtWahrscheinlich meinst du:
int ..., zahl; ... eingabe(i, &zahl);
-
free hast du auch vergessen. Liefere mal compilierbaren Code ab und dann kann man weitersehen.
Die Aufgabenstellung ist übrigens ebenso maximal suboptimal, es fehlt die Fehlerbehandlung.
-
Danke erstmal für die schnelle Hilfe. Aber jetzt denke ich, ich habe kein bisschen verstanden, was ich da machen soll.
Nur mal von der Struktur her:
-die main fragt wie lang das feld sein soll
-das gibt man ein
-die allocmem wird aufgerufen und man übergibt die gewünschte länge und was noch? Welche funktion hat der **ptrptr in der allocMem?
-Die allocmem initialisiert ein feld und reserviert speicher für die gewünschte länge
-Dann füllt sie das ganz ding mit nullen auf
-gibt dann einen Zeiger auf dieses Feld an die main zurück
und die fragt dann die einzelnen werte die man da eingeben möchte ab und speichert sie im feld
-wenn alle werte eingegeben sind löscht er alles wieder und das programm ist am ende
Hab ich das soweit richtig verstanden?@DirkB Die zeilen 7 und 8 verstehe ich nicht. Wie soll ich da mit void * arbeiten?
@wutz Wenn ich soweit wäre einen kompilierbaren Code abzuliefern, ist es meistens nichtmehr so ein Problem. Zumindest wars das bisher nicht
-
Hi,
hab jetzt nochmal einiges geändert. Er ruft nur einmal die allocmem auf und danach füllt er das feld dann mit einträgen. Nur leider habe ich keine Ahnung, wie die allocmem funktionieren soll. Von der Idee her so: malloc reserviert einen Speicherbereich in den ein Feld der Länge length passt und übergibt die Adresse des Anfangs dieses Bereichs.
Dann wird das Feld ab dieser Anfangsadresse gespeichert und mit nullen gefüllt. Aber wie schreibt man das so, dass er das macht? Ich bin am verzweifeln.#include <stdio.h> #include <stdlib.h> void allocMem (int length, void **ptrptr) { //ich habe nicht die leiseste Ahnung, was ich hier machen muss } void eingabe (int i, double *wert) { int a; printf("%d. Zahl eingeben", i); scanf("%d", &a); *wert=a; } int main() { int i=1,groesse; void *feld; double **input; printf("Geben Sie die gewuenschte Groeße ein"); scanf("%d", &groesse); allocMem(groesse,*feld); while(i<groesse) { eingabe(i,*input); **(feld+i-1)=*input; i++; } return(0); }
Danke
-
Als Trockenübung. Ich hoffe es sind nicht allzu viel Fehler drin
#include <stdio.h> #include <stdlib.h> void allocMem (int length, void **ptrptr); double eingabe (int i, double *wert) { double val; printf("%d. Zahl eingeben", i); scanf("%lf", &val); // du willst double einlesen if (wert != NULL) *wert = val; return val; // Man sollte den einen Funktionswert ruhig ausnutzen. } int main() { int i=0,groesse; double *feld; // das feld soll vom Typ double sein double input; // und du willst keine Zeiger oder so eingeben printf("Geben Sie die gewuenschte Groeße ein"); scanf("%d", &groesse); allocMem(groesse*sizeof(double),(void **)&feld); // Der Wert von feld soll verändert werden darum & // und ein double ist größer als 1 Byte while(i<groesse) { eingabe(i,&input); *feld+i=input; i++; } return(0); } void allocMem (int length, void **ptrptr) { //ich habe nicht die leiseste Ahnung, was ich hier machen muss void *ptr; ptr = .....// Hier musst du den Speicher besorgen memset(...); *ptrptr = (double *)ptr; }
Warum **ptrptr?
Weil du einen Zeiger verändern willst.
-
Variante, die auch das geforderte free nebst Kontrollausgabe als Testfall enthält; das unterschiedliche Argument bei scanf/printf sollte wohl anschaulich genug sein, wie man in C Parameter behandelt.
#include <stdio.h> #include <stdlib.h> void allocMem (int length, void **ptrptr) { *ptrptr = calloc(1,length*sizeof(double)); } void eingabe (int i, double *wert) { printf("%d. Zahl eingeben", i); scanf("%lf", wert); } int main() { int i,groesse; double *feld; printf("Geben Sie die gewuenschte Groesse ein"); scanf("%d", &groesse); allocMem(groesse,&feld); for(i=0;i<groesse;++i) { eingabe(i+1,&feld[i]); } for(i=0;i<groesse;++i) { printf("\n%d. %f",i+1,feld[i]); } free(feld); return(0); }