Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » char* free()'en

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
10.02.2003, 19:26 Uhr
MarcDuerner



Hi,
Ist folgendes korrekt?

const char* get_string(int a)
{
if(a==1)
{
char string[250] = "Hello World";
return string;
}

return 0;
}

Muss ich wenn a 1 ist und ich einen string aus der functionbekomme
denselben free()'en?

Marc
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
10.02.2003, 20:47 Uhr
virtual
Sexiest Bit alive
(Operator)


Nein, der Code ist nicht korrekt, weil char string[250] Eine lokale Variable ist, die nach verlassen der Routine nicht mehr existiert und überschrieben wird. Daher zeigt der Rückgabewert nach nirgendwo.
Dir dürfte Klar sein, daß sich in solchen Fällen C++ ganz gut macht, denn die Klasse std::string erledigt das Speicherhandling für dich. Wenn es aber doch C sein soll, hast Du im Wesentlichen drei Möglichkeiten:

1. Verwenden einer statischen Variable
Das sähe so aus:

C++:
onst char* get_string(int a)
{
    if(a==1)
    {
        [b]static[/b] char string[250] = "Hello World";
        return string;
    }

    return NULL;
}


Dieser Code ist korrekt, weil das "static" bewirkt, daß die lokale Variable auch nach dem Funktionsaufruf bestehen bleibt. Tatsächlich wirst Du in der einen oder anderen API solche Routinen finden, die genauso vorgehen. Der Nachteil ist natürlich, daß es diese Variable einmal gibt; dh wenn der String bei unterschiedlichen a's unterschiedliche Werte zurückgeben soll, wird string immer wieder überschrieben. Folgender Code illustriert das Problem:

C++:
const char* func(int x)
{
    static char buffer[100];
     switch (x)
      {
       case 1: strcpy(buffer, "eins");
                  break;
       case 2: strcpy(buffer, "zwei");
                  break;
       default: strcpy(buffer, "Soweit kann ich noch nicht zählen!");
                  break;
       }
      return buffer;
}

int main()
{
      const char* p1;
      const char* p2;

      p1 = func(1);
      p2 = func(2);

      printf("func(1) ergibt: %s\n", p1);
      printf("func(2) ergibt: %s\n", p2);
}


Der Vorteil ist, daß man sich einen Dreck ums Speicherhandling kümmern muß.
2. Dynamischer Speicher
Man kann es auch mit dynamischen Speicher machen, dann sieht deine Routine so aus:

C++:
const char* get_string(int a)
{
    if(a==1)
    {
        char* buffer;
        buffer = malloc(strlen("Hello World!")+1);
        if (buffer) strcpy(buffer, "Hello World!");
        return buffer;
    }
    return NULL;
}


Dieser Ansatz merzt zwar den Nachteil des Überschreibens vorheriger Funktionsergebnisse aus, hat aber den Nachteil, daß der Aufrufer dafür sorgen muß, daß der Speicher freigegeben wird, Der Aufrufer muß free() für das Funktionsergebnis aufrufen. Ein weiterer nachteil ist, daß man wenn die Rückgabe NULL ist, eigentlich nicht recht weiß, ob a!=1 war oder aber einfach kein Speicher vorhanden war (dh. der Aufrufer sollte errno==ENOMEM abfragen).
3. Aufrufer == Speichereigner
Dann gibt es natürlich auf die Möglichkeit, daß der Aufrufer eigentümer des Speichers ist und der Funktion mitteilt, wo und wie viel Speicher für das Ergebnis da ist:

C++:
const char* get_string(int a, char* ergebnis_buffer, int max_len)
{
    if(a==1)
    {
        if (strlen("Hello World")>=max_len)
        {
            /* Fehler: Rückgabebuffer zu klein */
            return NULL;
        }
        strcpy(ergebnis_buffer, "Hello World!");
        return ergebnis_buffer;
    }
    return NULL;
}


Zwar hat man mit diesem Ansatz auch vermutlich weniger Trouble mit Speicherhandling (zeit jedenfalls die Erfahrung), aber erstens ist der Funktionsaufruf ungleich komplizierter und zweitens kann man wieder nicht entscheiden: ist a!=1 oder aber der buffer einfach zu klein, wenn NULL zurück kommt.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 10.02.2003 um 20:47 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
10.02.2003, 20:54 Uhr
virtual
Sexiest Bit alive
(Operator)


Tschulige, du hast natürlich 4 Möglichkeiten:
Wechsel die Sprache
Benutze C++ und reuse bzw. entwickel eine Klasse, die das Speicherhandling zuverlässig managt.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
10.02.2003, 21:38 Uhr
MarcDuerner



Erstaunlicherweise funktioniert mein geposteter code, obwohl mir von
vorneherein klar war, dass string ein stack object der funktion ist und ich mit
return string; nur die addresse des char array zurückgebe. Die Tatsache das
es funktioniert hatte mich etwas stutzig gemacht.

Ich muss leider für diesen Fall C benutzen (C-library), sonst hätte ich
sebstverständlich std::string genommen.

Wie kann ich denn mit malloc ein 250 Zeichen char array on the heap
erzeugen? So?

char* s = malloc(250);

Marc
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: