Noch eine Frage zur Rückgabe von Zeigern
-
Hallo Leute,
muss euch noch mit einer Frage nerven, die ich mir auch noch nicht so richtig erklären kann:
Ich habe eine solche Funktion geschrieben:char *testfunc() { *str=(char *)malloc(sizeof(char)*11); sprintf(str,"%s","Hallo Welt"); //return str; return "Hallo Welt"; }
Wenn ich das 1. Return wieder einkommentiere, funktioniert die Funktion logischerweise, weil sich der Pointer str im Heap befindet und somit auch nach Beendigung der Funktion noch zur Verfügung steht und somit der aufrufenden Funktion die Adresse von str zugewiesen werden kann.
Wenn ich das "Programm" so lasse wie es momentan ist, dann funktioniert das aber auch. Mir ist aber nicht ganz klar wieso. Werden fixe Zeichenketten von C auch in einem Speicherbereich abgelegt, der nach Beendigung der Funktion noch zur Verfügung steht und es wird automatisch auch ein Pointer geliefert? Oder war das jetzt Zufall, dass das noch im Speicher stand? Sollte man solche fixen Zeichenketten zurückgeben, oder sollte man sie lieber mit Hilfe eines Pointers in den Heap knallen und dann zurückgeben?Danke mal wieder für eure Hilfe
David.
-
AFAIK existiert keien Garantie dafür, dass das so funktioniert und ist vom Standard her undefiniertes Verhalten.
btw.
1. caste nicht den Rückgabewert von malloc, da dies überflüssig und gefährlich sein kann2. sizeof(char) ist immer 1
3. wenn du strings kopieren willst, dann nimm memcpy oder strcpy. sprintf ist dafür zu langsam
-
ok, danke auch für die hinweise
zu 1. den cast muss ich leider machen, weil sonst mein compiler meckert. ich benutze den mingw-Compiler, der bei der Dev-C++ Entwicklungsumgebung von Bloodshed dabei ist, und da scheint er sich nicht ganz an den ANSI-C Standard zu halten. BTW: Ich hab in den Project Options natürlich eingestellt, dass ich ein C und kein C++ Programm kompilieren möchte.
Inwiefern kann das denn gefährlich sein?zu 2. ich weiß wohl dass sizeof(char) 1 ist, aber irgendwer hier auf dem Forum hat mir das mal gesagt, bzw. ich habs hier mal gelesen, damits auch zukünftig kompatibel ist, falls man irgendwann mal mehr Platz für char braucht, von wegen Erweiterung des Zeichensatzes oder was weiß ich
Jedenfalls hab ichs mir nun halt angewöhnt, dass so zu machen. Spricht doch auch nix gegen oder?zu 3. Das wusst ich nicht. Werde ich gleich mal ändern.
-
btw: es ist etwas - äh - unschön, wenn man von einer Funktion speicher reservieren lässt, da du dich dann irgendwann nach dem Funktionsaufruf selber um das Aufräumen (free) kümmern musst, bzw. es vergessen kannst, da du ja nirgends explizit "malloc" hast schreiben müssen.
Zumindest gut dokumentieren, dass man den zurückgelieferten Zeiger freigeben muss, solltest du schon. - nur so als tip.
-junix
-
das lässt sich leider in meinem speziellen fall nicht anders handlen
Ich möchte von einem Socket eine bestimmte Menge Daten empfangen, dazu sendet der Socket erst immer ein feste Anzahl Zeichen, die die Anzahl der eigentlich zuempfangenden Zeichen enthält und danach wird dementsprechend der Speicher reserviert und das eigentlich zu Empfangende wird empfangen Mir fällt keine Möglichkeit ein das anders zu machen, und muss da halt jetzt immer dran denken, aber ich pass da schon aufAber ansonsten geb ich dir natürlich recht, wo sich das machen lässt, mach ich das natürlich auch.
-
zu 2.
das ist absoluter blödsinn. sizeof(char) wird immer 1 sein. Wahrscheinlich hast du das nicht richtig verstanden. sizeof(wchar_t) ist natürlich nicht immer 1 (4byte auf neueren Platformen und 2 byte auf älteren Systemen idr.), da wchar_t für Unicode Zeichen ist.
-
ack.
dann kann ichs mir ja wieder abgewöhnen...bin mir aber ziemlich sicher, dass es um char ging. Aber muss ja auch nicht alles stimmen was hier steht...
-
kingruedi schrieb:
AFAIK existiert keien Garantie dafür, dass das so funktioniert und ist vom Standard her undefiniertes Verhalten.
Das ist falsch. Das Verhalten ist eindeutig definiert. String-Literale haben statische Lebensdauer, d.h. sie existieren während der gesamten Programmlaufzeit, von Anfang bis Ende.
-
Ist es nicht so, dass sämtliche Literale zusammen im Heap gespeichert werden und
dort wo sie im Programm verwendet werden ein Zeiger auf die Literale steht?So hab ich das jedenfalls verstanden.