Hellihello Martin,
brauch ich nicht einen char*** um den Parameter zu manipulieren?
uffffff ...
Ich habe mir das Konzept nochmal genau durch den Kopf gehen lassen. Ja, im Prinzip hast du Recht. Denn du gibst einen uninitialisierten char** in die Funktion hinein, die tut irgendwas damit, aber davon bekommt die übergeordnete Funktion nix mit. Wow.
Gut, dass ich die Logik scheinbar annähernd anfange zu begreifen. Im Zend-Framework arbeiten übrigens die einzelnen Funktionen (in dem Fall Klassen) auch unabhängig an einem Objekt, das dann nicht mal übergeben werden muss (ein Objekt übergeben heißt ja, die Referenz zu übergeben seit PHP5) sondern sich auch noch selber holt über die statische Methode (Singelton) einer Klasse, die das Objekt dann rausrückt. So "weiß" die aufrufende Funktion also im Grunde nicht, was die aufgerufen veranstaltet.
Ich habe solche Algorithmen bisher immer so gelöst, dass die aufrufende Funktion (caller) die Speicherreservierung vornimmt und der aufgerufenen Funktion (callee) dann einen Zeiger auf diesen reservierten Speicherbereich übergibt. Das ist einfacher zu überblicken und zu debuggen, und man kann die Funktion dann sowohl mit statisch als auch dynamisch reservierten Puffern verwenden.
Jau, das dachte ich erst auch. Drei Sterne Pointer sind für den Kopf schon relativ verschachtelt finde ich. Aber Vinzenz schlug ja vor, nur die Anzahl der Teilstrings zurückzugeben.
Nachteil: Der Speicherbedarf muss vorher bekannt sein (oder eine definierte Begrenzung haben),
Genau an dem Punkt war ich dann auch. Aber man könnte ja die Funktionen auch in Reihe schalten. Erst eine, die die Anzahl der Strings ermittelt, dann den Speicher reservieren und übergeben (oder so).
oder man muss Strukturen nutzen, die von sich aus eine dynamische Größe haben, etwa verkettete Listen. Einfacher ist das aber auch nicht.
Fein das. DoublyLinkedList gibt es als Klasse/Interface auch in der SPL von PHP https://forum.selfhtml.org/?t=175998&m=1168283. Diese Struktur ist ja nicht uninteressant.
Auf dein Beispiel übertragen könnte man das Dilemma aber umgehen, indem man die Semantik ändert. Ich würde
int function(char *, char **)
ändern in
char **function(char *, int *)
und dann den Zeiger auf den Speicherbereich, den die Funktion reserviert hat, als Funktionsergebnis zurückgeben (im Fehlerfall NULL), die Anzahl der Teilstrings dann über den int-Zeiger[*].
Jau, so hatte ich ja im Grunde versucht anzufangen.
"folgende funktion wird damit aufgerufen
char **
csvlinesplitting(char *line)"
https://forum.selfhtml.org/?t=177894&m=1172273
[viel Code]
ich habe mir jetzt nicht die Mühe gemacht, den Code im Einzelnen zu sichten, denn ich habe den Eindruck, du hast das Problem an sich erkannt.
Dank für die Rückmeldung. Das Gefühl bekomme ich langsam auch.
Aber bevor du da von Hölzchen auf Stöckchen kommst: Vielleicht geht's mit einem etwas anderen Ansatz einfacher.
//free allocated space
printf("free:\n");
free(mystrings);Damit gibst du allerdings nur die Zeiger auf die Strings frei, nicht die Strings selbst.
D.h. free(mystrings[0]) und free(mystring[1]), also die Pointer auf den reservierten Speicher für die Strings. free bekommt im Grunde die Adresse übermittelt, bzw. hat sich C in dem Zusammenhang mit der Adresse gemerkt, welcher Datentyp und welche Größe damit verunden ist?
Könnte ich, dem Verständnis halber, "int a = (int)&mystring[1]" (weise dem integer a die adresse von mystring[1] zu) und dann free((char*)a); (befreie den Speicher der aus dem integer zurückverwandelten Adresse(Pointer))?
[*] Wenn man es richtig machen will, prüft man innerhalb der Funktion noch, ob der int* gültig (nicht null) ist, und schreibt den Rückgabewert nur in diesem Fall. Not a bug, but a feature: Wenn die caller-Funktion die Anzahl nicht braucht, übergibt sie einfach NULL anstelle eines int*.
Aha, drüber nachdenken.
Dank und Gruß,