Vergrößern eines Zeigers mit realloc
-
Hi!
Ich hab da mal folgendes Problem. Und zwar habe ich im Haupt-programm einen Zeiger (Nennen wir ihn Zeiger 1) deklariert und in einer Funktion habe ich wiederrum einen Zeiger (Zeiger 2) der die Aresse des Zeiger 1 übergeben bekommt.
Jetzt lese ich in einer Funktion strings (char-arrays) ein und speichere diese in den Speicher auf den die beiden Zeiger zeigen. Um dies realisieren zu können muss ich allerdings mehrmals in der Funktion den Speicher des Zeiger 1 vergrößern.Wisst ihr wie ich aus der Funktion heraus den Zeiger in main() vergrößern kann?
Danke schonmal für die Antwort.
MfG O-M-A
-
Hey
Durch switch-case, und dann im case, die Funktion aufrufen.
-
Ja gut ... wie meinst u das
Ich habe halt in der Funktion eine for-Schleife in der aus einer Datei ein String gelesen wird. Dann frage ich die Größe des Strings ab und will en Zeiger 1 um diese Anzahl an Elemente vergrößern.
-
Du kannst mit Zeiger auf Zeiger arbeiten.
-
Ja gut as habe ich eben überlegt ...
Ob der Zeiger auf den gezeigt wird auch den neuen Speicherbereich zugewiesen bekommt oder ob dieser weiterhin auf den kleineren Bereich zeigt !?
-
One-Man-Army schrieb:
Wisst ihr wie ich aus der Funktion heraus den Zeiger in main() vergrößern kann?
ist das ein zeiger, der auf speicher zeigt, der mit 'malloc' (oder so) beschafft wurde? dann etwa so:
int new_size (void **p, int new) { void *q = realloc (*p, new); // erstmal speicher holen (versuchen zumindest) if (q == 0) return 0; // hat nicht geklappt *p = q; // neuen pointer einsetzen return 1; // hat geklappt; } // anwendung obiger funktion dann so: ... void *p = malloc (100); // originalgrössse if (new_size (&p, 200)) { // wurde erweitert } else { // hat nicht geklappt, p ist der alte } ...
^^ungetestet
-
Kann man mit malloc den Speicher auch vergrößern oder versteh ich gerade deinen Quelltext falsch ...
Zu deiner Frage:
Ja es ist ein char-Pointer auf einen Speicherbereich von zunächst mal einem Char. Danach soll er um weitere Char vergrößert werden.
-
Vergrößern/verkelinern kannst du mit realloc.
Guckst du frickys Code.
-
Ich glaube realloc ist der falsche Ansatz. Bau dir einen Buffer. http://www.c-plusplus.net/forum/viewtopic-var-p-is-1815221-and-highlight-is-.html#1815221
Das ist schonmal eine Grundlage. Du kannst dir noch das letzte Element merken damit es schneller geht und in jedem struct zum Beispiel 100 chars Speichern damit der Speicheroverhead kleiner wird. Dann vielleicht noch eine getelement(int position)-Funktion schreiben.
-
nwp2 schrieb:
Ich glaube realloc ist der falsche Ansatz.
Warum?
-
One-Man-Army schrieb:
Kann man mit malloc den Speicher auch vergrößern oder versteh ich gerade deinen Quelltext falsch ...
mit malloc nicht, aber mit 'realloc'
One-Man-Army schrieb:
Zu deiner Frage:
Ja es ist ein char-Pointer auf einen Speicherbereich von zunächst mal einem Char. Danach soll er um weitere Char vergrößert werden.geht nur, wie gesagt, wenn der pointer vorher schon auf speicher zeigte, der von malloc und co. kommt (oder wenn der pointer 0 ist), sonst nicht.
-
Tim schrieb:
nwp2 schrieb:
Ich glaube realloc ist der falsche Ansatz.
Warum?
So wie ich das sehe wird der entstehende Code kaum beherrschbar sein. Mit Buffern kann man mal eben die aktuelle Größe ausgeben oder eine Buffer Printfunktion basteln, bei realloc hat man keine Ahnung was eigentlich nach dem dritten realloc an Speicher da ist. In etwa dieselbe Argumentation warum man goto nicht verwendet wenn man nicht muss.
Wahrscheinlich ist es Geschmackssache, es gibt sicher Programmierer die eine realloc-Kette und goto's beherrschen, ich jedoch kann mir kaum 5 Minuten merken was ich eigentlich wollte, geschweige denn eine Woche, und wenn dann der Code nicht idiotensicher ist seh ich nicht mehr durch und muss ihn neu schreiben.
-
nwp2 schrieb:
bei realloc hat man keine Ahnung was eigentlich nach dem dritten realloc an Speicher da ist.
bei realloc siehste am rückgabewert, ob's geklappt hat oder nicht. realloc macht auch nichts kaputt, ist eigentlich ganz easy.
nwp2 schrieb:
Wahrscheinlich ist es Geschmackssache, es gibt sicher Programmierer die eine realloc-Kette und goto's beherrschen
du fürchtest dich vor realloc, goto und (anderer thread) #define? bist du sicher, dass C das richtige für dich ist? versuchs doch mal mit C++ *fg* aus keinem anderen grund ist C++ entstanden (sorry, volkard).
-
@fricky: Du siehst das falsch. Ich fürchte mich nicht vor goto, define und realloc. Ich bemühe mich nur lesbaren Code zu schreiben. Ich kann ungefähr 1000 Zeilen Code verstehen, danach streikt mein Hirn. Hab mit Qbasic angefangen, nach spätestens 1000 Zeilen Spaghetticode hab ich nicht mehr durchgesehen.
Deshalb strukturiere ich meinen Code so dass ich es nie mit mehr als 1000 Zeilen gleichzeitig zu tun kriege, am besten nichtmal mit 100. Wenn ich einen Buffer habe muss ich mich mit den Bufferfunktionen beschäftigen, die haben alle etwa 1-30 Zeilen Code. Danach kann ich alles wieder vergessen und einfach meine Funktionen benutzen.Wenn ich realloc benutze muss ich mir merken was dort genau gemacht wird und warum. Ein buffer->add(value) verstehe ich immer und kann im Zweifelsfalle mit einem buffer->print() vorher und nachher kucken obs geklappt hat. Ein void *q = realloc (*p, new); verstehe ich nicht genau. Ich weiß was realloc tut, aber nicht wieso da diese Zeile steht.
Das ist übrigens auch der Grund warum ich bei C bleibe und nicht zu C++ wechsle. Bei C steht eine Zeile wie i++; da. Ich weiß dass i irgendwas zahlenähnliches ist und um eins erhöht wird. Wenn ich dieselbe Zeile in C++ habe weiß ich garnichts. Es könnte ein Fenster aufgehen, oder eine Datei geöffnet werden oder sonstwas passieren, und bevor ich die ganzen Klassen bin in die Tiefe begriffen habe habe ich schon wieder vergessen was ich eigentlich machen wollte.
define hat seinen Sinn als Includeguard, außerdem kann man damit wunderbar printf-debugging ein und ausschalten. Als Variable ist ein define aber nicht sonderlich geeignet.
goto hat seinen Sinn wenn man aus einer mehrfach verschachtelten Schleife rausspringen will, gibt sicher noch andere sinnvolle Anwendungen. Eine if-goto-Kombo ist aber kein guter Ersatz für eine while-Schleife.
Was ich damit sagen will ist, dass all diese Dinge wo ich manchmal schreibe "benutz das nicht" schon ihren Sinn haben, aber in diesem Fall einfach nicht geeignet sind. Klar gehts, es ist nur ein unverständlicher fieser Hack den man später bereuen wird. Aber naja, unverständlich liegt im Auge des Betrachters. Im Allgemeinen werden hier jedoch keine Vollprofis Fragen stellen sondern Leute die noch weniger Ahnung haben als ich, und die wollen verständlichen Code (oder auch einfach nur fertigen funktionierenden Code, aber das ist nicht mein Problem).
Tut mir leid dass das alles komplett offtopic war
-
nwp2 schrieb:
Tim schrieb:
nwp2 schrieb:
Ich glaube realloc ist der falsche Ansatz.
Warum?
So wie ich das sehe wird der entstehende Code kaum beherrschbar sein. Mit Buffern kann man mal eben die aktuelle Größe ausgeben oder eine Buffer Printfunktion basteln, bei realloc hat man keine Ahnung was eigentlich nach dem dritten realloc an Speicher da ist. In etwa dieselbe Argumentation warum man goto nicht verwendet wenn man nicht muss.
Es ist im wesentlichen gar keine Argumentation, eben weil du keine Argumente lieferst. Du baust dir Listen, nennst sie Buffer, findest das ganz toll. Aber ansonsten kann ich z.B. nicht nachvollziehen was an einer auf realloc-basierenden Lösung "nicht beherrschbar" sein soll. Das ist ein absolutes Standard"problem".
-
nwp2 schrieb:
@fricky: Du siehst das falsch. Ich fürchte mich nicht vor goto, define und realloc. Ich bemühe mich nur lesbaren Code zu schreiben. Ich kann ungefähr 1000 Zeilen Code verstehen, danach streikt mein Hirn.
naja, du musst deinen code gut strukurieren, dann brauchste dir nicht jede einzelne programmzeile zu merken, oder zu jeder zeit ganz genau zu wissen, wie irgendein programmteil im innern funktioniert. software besteht normalerweise aus einigen grossen 'blöcken', die ihrerseits in kleinere komponenten unterteilt sind usw. je nachdem, auf welchen level du dich begibst, hast du's mit einer überschaubaren menge zu tun (so sollte es jedenfalls sein).
z.b. ein kfz-mechaniker, stellt sich auch nicht jede schraube des autos einzeln vor, wenn er irgendwo am motor bastelt, oder gar wie darin irgendwelche elektronen um atomkerne schwirren *fg*
-
;fricky schrieb:
z.b. ein kfz-mechaniker, stellt sich auch nicht jede schraube des autos einzeln vor, wenn er irgendwo am motor bastelt, oder gar wie darin irgendwelche elektronen um atomkerne schwirren *fg*
Aber Scotty, der kennt jeden Transistor eines jeden ICs mit Namen.
-
nwp2 schrieb:
So wie ich das sehe wird der entstehende Code kaum beherrschbar sein. Mit Buffern kann man mal eben die aktuelle Größe ausgeben oder eine Buffer Printfunktion basteln, bei realloc hat man keine Ahnung was eigentlich nach dem dritten realloc an Speicher da ist. In etwa dieselbe Argumentation warum man goto nicht verwendet wenn man nicht muss.
Wahrscheinlich ist es Geschmackssache, es gibt sicher Programmierer die eine realloc-Kette und goto's beherrschen, ich jedoch kann mir kaum 5 Minuten merken was ich eigentlich wollte, geschweige denn eine Woche, und wenn dann der Code nicht idiotensicher ist seh ich nicht mehr durch und muss ihn neu schreiben.
Da hst Du die grundlegend falsche Denke.
Grade wenn man Programme korrekt anlegt, kann's Dir nächste Woche wurscht sein, WIE Dein Programm funktioniert, solange Du dokumentiert hast, WAS es genau tut. Erst wenn was nicht wie erwartet funzt, mußt Du nochmal in den Code rein. Ideal also für Alzheimer- Programmierer.Bedeutet, Du mußt alles möglichst gekapselt anlegen, aber auch wenn Du Zeiger auf Speicherblöcke modulübergreifend durch die Gegend reichst, ist da auch nichts Bedrohliches dran, wenn Dein Modul einen Init- Teil und einen Destruct- Teil enthält.
Übrigens ist goto das perfekte Mittel, um innerhalb von Funktionen cleanups unterzubringen, das schafft sogar echt Übersicht.Big Brother schrieb:
Aber Scotty, der kennt jeden Transistor eines jeden ICs mit Namen.
Plus den gesamten Quellcode des Bordcomputers.
-
Hi Leute,
Sorry das meine Frage nicht genau das Problem des OP betrifft, aber ich wollte eine konkrete Frage stellen zu dem Code den ;fricky gepostet hat:
Das **p bedeutet was? Zeiger auf einen Zeiger oder was genau?
Und warum ist das nötig? Kann man nicht einfach den Zeiger übergeben?
Sorry, wenn die Fragen dumm sind oder so, aber ich kapier es nicht...MfG ::john::
-
john schrieb:
Zeiger auf einen Zeiger oder was genau?
Und warum ist das nötig? Kann man nicht einfach den Zeiger übergeben?
...MfG ::john::Rischtisch! Wenn Du nur den Zeiger übergeben würdest, wäre das ja nur eine Kopie des Zeigers, die Du reingibst. C hat ja by default nur einen "call by value". Du mußt also die Referenz des Pointers übergeben und das ist nunmal pointer auf pointer.
Jetzt etwas klarer?