String von Funktion übergeben

Von: , Frage gestellt am So, 9. Nov 2008

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;) des Strings zurückzugeben, haben auch nicht geklappt.

Besten Dank.
MfG Peter

10 Antworten zu dieser Frage

  1. Antwort von nach 2 Stunden 0 hilfreich
    Re: String von Funktion übergeben

    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;) 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.

    • Antwort von nach 18 Stunden 0 hilfreich
      Re^2: String von Funktion übergeben

      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

      • Antwort von nach 20 Stunden 0 hilfreich
        Re^3: String von Funktion übergeben

        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)

  2. Antwort von nach 10 Stunden 0 hilfreich
    Re: 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.
    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;) 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 <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    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 <=", (unsigned int) p);
    return p;
    }
    int main()
    {
    char *p1 = get_string("A");
    char *p2 = get_string("B");
    char *p3 = get_string("C");
    puts(p1);
    puts(p2);
    puts(p3);
    return 0;
    }
    


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

    Grüße

    CMБ

    • Antwort von nach 18 Stunden 0 hilfreich
      Re^2: String von Funktion übergeben

      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

      • Antwort von nach einem Tag 0 hilfreich
        Re^3: String von Funktion übergeben

        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

        • Antwort von nach einem Tag 0 hilfreich
          Re^4: String von Funktion übergeben

          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" ;-)

          Grüße

          CMБ

  3. Antwort von nach 14 Stunden 0 hilfreich
    Re: String von Funktion übergeben

    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;) 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 <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #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 <=", str.s);
    return str;
    }
    int main()
    {
    STRING s1 = get_str("A");
    STRING s2 = get_str("B");
    STRING s3 = get_str("C");
    puts(s1.s);
    puts(s2.s);
    puts(s3.s);
    return 0;
    }
    


    Grüße

    CMБ

  4. Antwort von nach einem Tag 0 hilfreich
    Re: String von Funktion übergeben

    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



Keine passende Antwort gefunden? Jetzt eigene Frage stellen!