realloc : Verständnis / Rechenproblem
-
beginner88888 schrieb:
Hallo,
wäre es nicht viel besser, wenn du vor dem Einlesen die maximale Größe der Datei (bzw. des auszulesenden Bereichs) bestimmst
DAS... wäre die "supreme" Lösung, nur leider hab ich nicht den blassesten Schimmer wie ich das machen soll.
Entweder mit plattformspezifischer Funktion stat (ist aber auf so gut wie allen Plattformen vorhanden); oder ans Ende springen, Position bestimmen, wieder an den Anfang springen. Guck mal in eine Referenz des stdio.h-Headers, da findest du entsprechende Funktionen.
Prinzipell würde das mit dem realloc aber gehen oder? Also mit jedem durchlauf erhöhen?
Ja.
-
Entweder mit plattformspezifischer Funktion stat (ist aber auf so gut wie allen Plattformen vorhanden); oder ans Ende springen, Position bestimmen, wieder an den Anfang springen. Guck mal in eine Referenz des stdio.h-Headers, da findest du entsprechende Funktionen.
Werd ich machen, da dies wie schon geschrieben bestimmt die feinste ARt ist.
Aber es Bleibt:
Zitat:
Prinzipell würde das mit dem realloc aber gehen oder? Also mit jedem durchlauf erhöhen?
Ja.Wäre das dann korrekt:?
int *iptr; iptr=malloc(sizeof(int)*2); //Könnte jetzt 2 Werte Speichern?? *iptr=5; iptr++; // Wenn ich jetzt den Zeiger erhöhe, befindet er sich noch in dem zugewiesenen Speicher?? *iptr=10; // Das kann doch nicht gehen so oder? Wenn ich den Zeiger erhöhe, passt das dann schon noch?? iptr=realloc(iptr, sizeof(int)); // Jezt + 1 INT ??
-
Das ist völliger Quark. Guck dir mal ein paar Referenzen oder Beispiele zu realloc an.
-
Du hättest auch mal in die FAQ sehen sollen:
Dynamischer Speicher mit malloc/calloc/realloc/freeUnd hier auch der passende Beitrag für die Größe einer Datei:
Anzahl der Zeichen in einer TextdateiOder eben alternativ mittels der von SeppJ erwähnten Funktion stat, s. z.B. Zugriff auf das Dateisystem (P.S: Die Überschrift darin, ist aber mal wieder goldig
-
Ja, werd ich machen.
Das Zeigererhöhen ist schon falsch oder? Da geh ich aus dem reservierten Speicher raus??
-
Aus den Links:
// für ptr wurde bereits Speicher reserviert ptr = realloc ( ptr, 10 * sizeof(*ptr) );
soweit bin ich dann aber mit dem realloc nicht weg, sizeof(*ptr) ist bei mir sizeof(int).
Die Überprüfung von realloc mit dem temp jetzt mal aussen vor.
-
Das was du da vorher mit dem Pointer anstellst ist aber total verkehrt. Ich bin mir nicht sicher, dass du verstanden hast, was realloc macht. realloc fügt keinen Speicher an irgendeiner Stelle ein. realloc nimmt einen mit malloc reservierten Speicherbereich und gibt einen zurück, der eine andere Größe hat.
-
Heut steh ich wohl nicht nur auf dem Schlauch....
das was du da vorher mit dem Pointer anstellst ist aber total verkehrt
Platz für 2 Werte, 2 Werte schreiben? Ich checks heut echt nciht.
realloc nimmt einen mit malloc reservierten Speicherbereich und gibt einen zurück, der eine andere Größe hat.
...inklusive dessen was schon im speicher steht. So hab ichs gelesen.
Und aus dieser Quelle:
http://pronix.linuxdelta.de/C/standard_C/c_programmierung_17.shtmlHabe ich schon den Eindruck geahabt,
das :int *ptr; ptr=malloc(sizeof(int)*2)
...Speicherplatz für 2 INT Werte reserviert, die ich wie ein Array behandeln kann.
*ptr=5 // 1. Speicherplatz *(ptr+1)=10 // wäre ptr++ und dann *ptr=10 nicht dasgleiche? jedenfalls 2. Speicherplatz.
Ich habe es so verstanden, das ich nun mit
ptr=realloc(ptr, WERT)
den bereits Vorhandenen Speicherplatz um X Elemente vergrößere wenn WERT=sizeof(int)*X und die bisherigen "Einträge" nicht verliere.von "http://pronix.linuxdelta.de/C/standard_C/c_programmierung_17_1.shtml" :
Bei einer Vergrößerung des Speicherplatzes mit realloc() behält der vordere Teil auf jeden Fall seinen Wert, und der neue Teil wird einfach hinten angehängt. Dieser angehängte Wert ist aber wie bei malloc() undefiniert.
-
Das Missverständnis scheint wohl zu sein, dass
ptr++
etwas sehr anderes ist alsptr + 1
.
-
Der Vorhang lüftet sich.
Ich benutze ptr++ normal so
int arr[10], *iptr; iptr=arr; *iptr=5; iptr++; *iptr=10; usw usw
In einer Schleife hald.
Bei meinem vorherigen Codes, würde das ptr++ den Zeiger erhöhen, da es aber kein richtiges Array ist, zeigt er hald irgendwohin, *(ptr+X)=Y weist aber dem Xten Element des "Arrays" das mit Malloc oder Realloc erzeugt wurde den Wert Y zu.
Richtig soweit?Aber würde dann in einer schleife der Code:
*(zeiger+X)=Wert; // Zeiger vorher z.B.. zeiger=malloc(sizeof(int)*2); zeiger=realloc(zeiger, sizeof(int)); // Verkleinert den Speicher?
.. bei jedem Durchlauf das "Array" um einen Speicherplatz erhöhen, oder müsste es:
zeiger=realloc(zeiger, aktuelle_Größe + sizeof(int)); //ist für aktuelle_Größe sizeof(zeiger) möglich? nicht oder? liefert nur die Größe des Zeigers .
sein? aktuelle_Größe könnte ich ja mit Hilfe einer Laufvariablen in der Schleife ermitteln...?
-
Du darfst aber nur den Zeigerwert an realloc() geben, den du mit malloc() (oder einem vorherigen realloc())-Aufruf erhalten hast, d.h. du darfst den nicht einfach ändern.
Du müßtest dir den Originalzeiger in einer anderen Variable speichern, z.B.
int *iptr, *tmp; iptr=malloc(sizeof(int)*2); //Könnte jetzt 2 Werte Speichern?? tmp = iptr; *iptr=5; iptr++; *iptr=10; iptr=realloc(tmp, sizeof(int)*3);
Sonst kann die realloc()-Methode nichts mit dem Zeigerwert anfangen (da sie intern eine Liste aller Speicherblöcke verwaltet und den übergebenen Wert überprüft, ob sie ihn kennt - denn sie muß nach dem Kopieren ja den alten Speicher mit freee() wieder freigeben).
Besser wäre im obigen Code naürlich, daß du den Originalzeiger behältst und für die Änderung dem temporären Zeiger verwendest, also
int *iptr, *tmp; iptr=malloc(sizeof(int)*2); tmp = iptr; *tmp=5; tmp++; *tmp=10; iptr=realloc(iptr, sizeof(int)*3);
So ich hoffe, jetzt ist dir ein bißchen mehr klar geworden über die Speicherverwaltung und den Umgang mit Zeigern.
-
So ich hoffe, jetzt ist dir ein bißchen mehr klar geworden über die Speicherverwaltung und den Umgang mit Zeigern.
Nö, ich dachte ich habe mir gerade hergeleitet, warum
*ptr=5;
ptr++;
*ptr=10;falsch ist. Was nun? ptr++ bringt mich doch aus dem Bereich den ich "reserviert" habe raus oder etwa nicht?
Ich würde es jetzt so machen, alles zusammengefasst was ich nun zu verstehen glaube:
int *iptr; *tmp, i=0; iptr=malloc(sizeof(int)); tmp=iptr; while (irgend_eine_abbruchbedingung) { *(iptr+i)=Value; // Davon ausgegangen das Value passend reinkommt i++; iptr=realloc(tmp, sizeof(int)*i); //Ohne Überprüfung jetzt ob realloc oder malloc nicht in die Hose gingen }
-
Ist ok, aber wenn du sowieso nicht prüfst, kannst du dir den Umweg über tmp auch sparen.
Dir ist bekannt, dass
*(foo + X)
das gleiche ist wiefoo[X]
?
-
Ja, das ist mir bekannt. Ich mach´s mal so und mal so. Ist eher geschmackssache oder??
Das mit tmp dacht ich mir fast, trotzdem Danke @Th69Bitte noch eine Antwort:
Th69 hat in meinem / seinen Code ja ptr++ benutzt.Stimmt meiner Herleitung, warum ptr++ falsch ist?
Ich benutze ptr++ normal so
int arr[10], *iptr; iptr=arr; *iptr=5; iptr++; // Zeiger auf das nächste Element des "richtigen" Arrays *iptr=10; usw usw //In einer Schleife hald.
ABER : Bei meinem vorherigen Codes
int *iptr; iptr=malloc(sizeof(int)*2)); // Speicher für 2 INT *iptr=5; iptr++; *iptr=10; // würde irgendwohin schreiben??
, würde das ptr++ den Zeiger zwar auch erhöhen , da es aber kein "richtiges" Array ist( Er zeigt nur auf einen mit malloc vergrößterten Speicherbreich), würde er hald irgendwohin zeigen, aber nicht mehr im "Bereich" liegen?!?, *(ptr+X)=Y weist aber dem Xten Element des "Arrays" das mit Malloc oder Realloc erzeugt wurde den Wert Y zu.
Richtig soweit?
-
Nein, du darfst ruhig ptr++ machen.
Damit gehst du dann zum nächsten int, genauso wie beim regulären Array halt auch.
Das Problem ist lediglich, dass realloc die von malloc erhaltene Adresse will, nicht eine, die ein paar Bytes weiter ist.
-
DDAANNKKEEE!!!!!!
Die Erklärung wäre ne Seite eher gut gewesenAlso ist Speicher der von Malloc kommt, genauso zu handeln wie wenn es ein normales Array wäre.
SeppJ :
Das Missverständnis scheint wohl zu sein, dass ptr++ etwas sehr anderes ist als ptr + 1.
Was wolltest du mir dann damit sagen? Wenns ein Array ist...
int *ptr; int arr[10]; ptr=arr; *ptr=5; // = ptr[0] oder arr[0] mit wert befüllen ptr++; // Zeiger erhöhen *ptr=10 // = ptr[1] oder arr[1] mit wert befüllen // ist doch dann kein unterschied zu ptr=arr; *ptr=5; *(ptr+1)=10 // arr[1] *(ptr+3)=15 // arr[3]
????
-
Was wolltest du mir dann damit sagen?
Ich ging zu der Zeit noch davon aus, dass du ungefähr wüsstest, wie realloc funktioniert. Somit:
ptr++; // Zeiger erhöhen ... // ist doch dann kein unterschied zu ... *(ptr+1)=10 // arr[1]
Die Änderung von ptr ist kein erwähnenswerter Unterschied? Gerade bezüglich realloc ist das sehr entscheidend, wie du nun gelernt hast.
-
Kapiert, das "Handling" ist kein unterschied. Für realloc natürlich schon.
Kapiert. => Pointer Handling war aber OK, wenn man realloc weglässt, ja??War nicht böse gemeint oder so.
Hab heut auf die laaaange Tour gelernt...
Abschließend:
int *iptr; *tmp, i=0; iptr=malloc(sizeof(int)); tmp=iptr; while (irgend_eine_abbruchbedingung) { *(iptr+i)=Value; // Davon ausgegangen das Value passend reinkommt i++; iptr=realloc(tmp, sizeof(int)*i); //Ohne Überprüfung jetzt ob realloc oder malloc nicht in die Hose gingen }
beim ersten Durchlauf ist i : 0, beim zweiten 1, beim 3: 3 usw, klar , aber wenn realloc
von "http://pronix.linuxdelta.de/C/standard_C/c_programmierung_17_1.shtml" :
Zitat:
Bei einer Vergrößerung des Speicherplatzes mit realloc() behält der vordere Teil auf jeden Fall seinen Wert**, und der neue Teil wird einfach hinten angehängt**. Dieser angehängte Wert ist aber wie bei malloc() undefiniert.dann hänge ich doch mit dem "*i" zuviel an oder? Ziel wäre ja immer noch pro Durchlauf um 1 zu erhöhen, muss ich den aktuellen "Stand" berücksichtigen??
-
Das hast du immer noch falsch verstanden. Nach dem realloc hast du so viel Speicher, wie du dem realloc sagst. Wenn der Bereich dazu vergrößert werden muss, dann bleiben die Werte im alten Bereich dabei erhalten.
-
OK. Jetzt alles klar. War ne schwere Geburt