String von Funktion übergeben

Hallo,
wie kann ich einen String übergeben, den ich erst in der Funktion erstellt habe?
Das Problem ist, dass der Speicher gelöscht wird, nachdem die Funktion beendet ist. Der Zeiger auf den String zeigt also nur noch ins Leere. malloc möchte ich auch nicht verwenden, da ich sonst den Speicher manuell wieder freigeben müsste.

Kann ich nicht irgendwie die Rückgabe als Zeichenkette erzwingen?
Also return „hallo“ funktioniert ja auch. Meine bisherigen Versuche, den Inhalt (also: return *string:wink: des Strings zurückzugeben, haben auch nicht geklappt.

Besten Dank.
MfG Peter

Hallo Auchfalls,

Also return „hallo“ funktioniert ja auch.

Ja, aber nur weil „hallo“ eine konstaten ist und in einem anderen Bereich abgelegt wird.

Meine bisherigen
Versuche, den Inhalt (also: return *string:wink: des Strings
zurückzugeben, haben auch nicht geklappt.

Der Zeiger zeicht ja auch auf den Bereich, welcher nacht funktions-ende gelöscht wird.

Eine Lösung wäre folgende, die aber auch ein Problem hat.
Sauber geht es nur mit malloc()

char \*get\_string(void)
{
 static char text[100];

 strncpy(text, "Da bin ich jetzt drin.", sizeof(text));

 return text;
}

Um das Problem zu zeigen: Diese Variante funktioniert identisch und hat das selbe Problem:

char text[100];

char \*get\_string(void)
{
 strncpy(text, "Da bin ich jetzt drin.", sizeof(text));

 return text;
}

bei jedem Aufruf von get:string() wird text[] verändert, was zu ungewollten Seiteneffekten führen kann.

void test(void)
{
 char \*s;
 char \*s1;

 s = get\_string();
 puts(s);

 strcpy(s, "Hallo!");
 puts(s);

 s1 = get\_string();
 puts(s);
 puts(s1);
}

Die Ausgabe müsste folgende sein:

Da bin ich jetzt drin.
Hallo!
Da bin ich jetzt drin.
Da bin ich jetzt drin.

MfG Peter(TOO)
P.S: ich hoffe es hat keien Tippfehler, hab den code nicht durch den Compiler gejagt.

Hallo,

wie kann ich einen String übergeben, den ich erst in der
Funktion erstellt habe?
Das Problem ist, dass der Speicher gelöscht wird, nachdem die
Funktion beendet ist. Der Zeiger auf den String zeigt also nur
noch ins Leere. malloc möchte ich auch nicht verwenden, da ich
sonst den Speicher manuell wieder freigeben müsste.

Aber nur, wenn der String als „automatische Variable“
(auf dem Stack) erzeugt wurde.

Kann ich nicht irgendwie die Rückgabe als Zeichenkette
erzwingen?
Also return „hallo“ funktioniert ja auch. Meine bisherigen
Versuche, den Inhalt (also: return *string:wink: des Strings
zurückzugeben, haben auch nicht geklappt.

Ich verstehe Dein Problem nicht ganz. Warum nochmal
kannst Du kein malloc nehmen? Werden die Strings so
groß, daß der Virtuelle Speicher der Rechners nicht
ausreicht?

Du *mußt* nämlich gar nicht die malloc’ed-Strings
wieder freigeben, Du *kannst* aber. Wenn Dein
Programm beendet wird, gibt das *Betriebssystem*
diesen Speicher sowieso frei.

Also sowas wäre imho ok.:

 #include 
 #include 
 #include 

 char \*get\_string(char \*pText)
{
 char \*p = (char \*)malloc(200\*sizeof(char) + strlen(pText) + 1);

 strcpy(p, pText);
 strcat(p, ":");
 sprintf(p+strlen(p), "\taddr =\> %X 

Ansonsten gibt es in C keine (unkomplizierte)
Möglichkeit, so etwas zu bewerkstelligen. In
C++ sähe das schon anders aus.

Grüße

CMБ

Hallo nochmal

Kann ich nicht irgendwie die Rückgabe als Zeichenkette
erzwingen?
Also return „hallo“ funktioniert ja auch. Meine bisherigen
Versuche, den Inhalt (also: return *string:wink: des Strings
zurückzugeben, haben auch nicht geklappt.

Anmerkung:

Das mit { return „Hallo“ } funktiert dann,
wenn „hallo“ in einem statischen Speicherbereich
liegt - der Compiler muß ja den String „hallo“
irgend wo hinterlegt haben.

Ansonsten kann man sich mit einem Trick be-
helfen, indem man das Feld (String ist ja ein
char-Feld) in eine Struktur verpackt. Dadurch
wird der String mit der Struktur kopiert:

 #include 
 #include 
 #include 

 #define MY\_STRINGLEN 256
 typedef struct { char s[MY\_STRINGLEN];} STRING;


 STRING get\_str(char \*pText)
{
 STRING str;
 
 strcpy(str.s, pText);
 strcat(str.s, ":");
 sprintf(str.s+strlen(str.s), "\taddr =\> %X 

Grüße

CMБ

Danke für deine ausführliche Antwort!

Sauber geht es nur mit malloc()

Wenn ich malloc in einer Funktion verwende, müsste ich doch nach jeden Funktionsaufruf diesen Speicherbereich wieder freigeben.?
Wird nicht sonst bei jeden Funktionsaufruf ein weiterer Bereich im Arbeitsspeicher reserviert? z.B. wenn ich die Funktion durch eine schleife 100x aufgerufen wird - Wird dann 100x der Platz im Arbeitsspeicher reserviert oder überschreibt malloc immer den gleichen Bereich?

Wie erfolgt eigentlich die String-Rückgabe von offiziellen Funktionen?

MfG Peter

Danke für die Antwort.

malloc möchte ich auch nicht verwenden, da ich
sonst den Speicher manuell wieder freigeben müsste.

Aber nur, wenn der String als „automatische Variable“
(auf dem Stack) erzeugt wurde.

Sry. Das verstehe ich nicht.

Ich verstehe Dein Problem nicht ganz. Warum nochmal
kannst Du kein malloc nehmen? Werden die Strings so
groß, daß der Virtuelle Speicher der Rechners nicht
ausreicht?

Wenn die Funktion durch eine Schleife z.B. 500 mal aufgerufen wird, dann kostet das 500*sizeof(array) Byte (=1,5 MB bei einem int Array mit 100 Elementen - okay beim Strings sind weniger) Speicher. oder irre ich mich da?

Du *mußt* nämlich gar nicht die malloc’ed-Strings
wieder freigeben, Du *kannst* aber. Wenn Dein
Programm beendet wird, gibt das *Betriebssystem*
diesen Speicher sowieso frei.

Wenn ich das mit allen FUnktionen so mache und das Programm eine sehr lange Laufzeit hat, dann kann bällt es sich zum riesen auf (wenn ich oben nicht falsch liege).

MfG Peter

Hallo Fragewurm,

Sauber geht es nur mit malloc()

Wenn ich malloc in einer Funktion verwende, müsste ich doch
nach jeden Funktionsaufruf diesen Speicherbereich wieder
freigeben.?

Also dann, wenn die Variable nicht mehr benötigt wird.

Wird nicht sonst bei jeden Funktionsaufruf ein weiterer
Bereich im Arbeitsspeicher reserviert? z.B. wenn ich die
Funktion durch eine schleife 100x aufgerufen wird - Wird dann
100x der Platz im Arbeitsspeicher reserviert oder überschreibt
malloc immer den gleichen Bereich?

Nein, wird immer ein neuer Block abgelegt.

Wie erfolgt eigentlich die String-Rückgabe von offiziellen
Funktionen?

Schau dir mal die str…() an.
Man übergibt immer einen Zeiger auf eine Variable. Diese wird also vom übergeordneten Programm angelegt und verwaltet.

MfG Peter(TOO)

Hallo,
wie kann ich einen String übergeben, den ich erst in der
Funktion erstellt habe?

Die einfachste Lösung wäre meiner Ansicht nach, einen std::string aus der STL zu verwenden. Wenn du C++ und nicht reines C verwendest. Beim reinen C wirst du nicht umherkommen, entweder malloc zu verwenden, oder der Funktion einen Zeiger auf einen Puffer zu übergeben (und einen int für die Puffergröße), in den sie den String hineinschreiben soll.

Viele Grüße,
Sebastian

Wenn ich das mit allen FUnktionen so mache und das Programm
eine sehr lange Laufzeit hat, dann kann bällt es sich zum
riesen auf (wenn ich oben nicht falsch liege).

Richtig, Semjons Rat ist ein ganz schlechter. Sich einfach nicht um die Speicherfreigabe zu kümmern, kann man bei einem 30-zeiligen Spaß- und Ausprobierprogramm machen. Aber in ernsthaftem Code ist es eine Todsünde.

Viele Grüße,
Sebastian

Hallo,

Wenn ich das mit allen FUnktionen so mache und das Programm
eine sehr lange Laufzeit hat, dann kann bällt es sich zum
riesen auf (wenn ich oben nicht falsch liege).

Richtig, Semjons Rat ist ein ganz schlechter. Sich einfach
nicht um die Speicherfreigabe zu kümmern, kann man bei einem
30-zeiligen Spaß- und Ausprobierprogramm machen. Aber in
ernsthaftem Code ist es eine Todsünde.

Nee, nee, das ist hier genau wie bei
„John Daniels“. Nicht jeder darf den
so nennen und nicht jeder darf einfach "
Speicher nicht freigeben" :wink:

Grüße

CMБ

hallo Leute,

Hallo,
wie kann ich einen String übergeben, den ich erst in der
Funktion erstellt habe?

Die einfachste Lösung wäre meiner Ansicht nach, einen
std::string aus der STL zu verwenden. Wenn du C++ und nicht
reines C verwendest. Beim reinen C wirst du nicht umherkommen,
entweder malloc zu verwenden, oder der Funktion einen Zeiger
auf einen Puffer zu übergeben (und einen int für die
Puffergröße), in den sie den String hineinschreiben soll.

Finde ich gut. Alternativ kann man auch eine verkettete Liste machen, mit einer Struktur, wie Semjon sie vorgeschlagen hat, und dann den Zeiger auf das erste Element zurueck geben.
Das geht auch mit C.

lG an alle
Martin B