Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » malloc und free bei Fkt mit Rückgabewert?

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
03.12.2004, 08:56 Uhr
~_Michael_
Gast


Hallo,

ich habe mal eine Frage: Ich habe eine Funktion, die mir einen struct als Rückgabewert liefert. In dieser Fkt. forder ich mit malloc() Speicher an, dann bearbeite den struct um ihn schließlich mitzurückzugeben. Aber muss ich dann nicht auch wieder Speicher freigeben??

Die struct DATEN hab ich oben definiert..

Funktion

C++:
struct DATEN* DatenSchreiben(WORD Index)
{
(...)
struct DATEN *Daten;
Daten=(struct DATEN *)malloc(sizeof(struct DATEN));
(...)
return Daten;
}
{


Muss ich 'Daten' am Ende wieder freigeben? Und kann ich es dann noch als Rückgabewert verwerten?

Vielen Dank
Michael
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
03.12.2004, 09:44 Uhr
~mike
Gast


Hi!
Wenn du in einem Programm nen Speicher reservierst und du beendest das Programm dann (in main: return X, exit(X) ,...) wird der Speicher von alleine wieder freigegeben.
Zur Laufzeit musst du es immer selbst machen. Wichtig dabei ist, dass du den Zeiger - welchen du von malloc zurückgeliefert bekommst, nie "verlierst". Ohne dem geht kein free und du hast ein memory leak.

mfg
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
03.12.2004, 10:00 Uhr
~_Michael_
Gast


Hallo mike,

ja, das ist mir klar, aber wie mache ich das denn jetzt in diesem Fall? die Fkt. wird mehrmals zur Laufzeit aufgerufen, also müsste ich doch den Speicher wieder freigeben, aber kann das gehen:


C++:
struct DATEN* DatenSchreiben(WORD Index)
{
(...)
struct DATEN *Daten;
Daten=(struct DATEN *)malloc(sizeof(struct DATEN));
(...)
free(Daten);  
return Daten;
}



Ich meine, ist die Information nicht verloren, wenn ich mit free() vor return arbeite??

Michael
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.12.2004, 10:21 Uhr
Bruder Leif
dances with systems
(Operator)


Moin!

free() ist eine "ganz normale C-Funktion", die nur den Zeiger braucht, um was freizugeben - wie oft der zwischen den Funktionen rumgereicht wurde, ist egal. Funktionen, die etwas erzeugen und dann zurückgeben, nennt man allgemein "Generatorfunktionen", die sind gang und gäbe. Paß einfach auf, daß Du den Speicher wieder freigibst
--
Mit 40 Fieber sitzt man nicht mehr vor dem PC.
Man liegt im Bett.
Mit dem Notebook.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.12.2004, 10:50 Uhr
~mike
Gast


@_Michael_:
Was du da machst ist ganz schlecht:

C++:
#include <stdio.h>

int main(void)
{
   char *c;
   c = (char *)malloc(sizeof(char));
   *c = 'A';
   printf("Vor free: %c\n", *c);
   free(c);
   printf("Nach free: %c\n", *c);

   return 0;
}


In diesem Fall würde folgendes erscheinen:
Vor free: A
Nach free: A

Scheint ja alles ok zu sein - aber du schreibst/liest hier in einem Speicherbereich, welchem deinem Programm nicht gehört. Darum immer folgendes schreiben:

C++:
#include <stdio.h>

int main(void)
{
   char *c;
   c = (char *)malloc(sizeof(char));
   *c = 'A';
   printf("Vor free: %c\n", *c);
   free(c);
   c = NULL;
   printf("Nach free: %c\n", *c);

   return 0;
}


Das läßt dein Program böse abkacken, aber dann merkst du den Fehler:
Vor free: A
Bus error

Das bedeutet dann, dass du eine Speichermanipulation auf einem nicht reservierten Speicher durchführen willst.
Also in deinem Fall ist free aufzurufen, wenn du die Daten nicht mehr benötigst. Wenn du ne Art Datenbank basteln willst, würde ich ein array aus struct DATEN nehmen, um sicher zu gehen, dass ich keine pointer verliere.

mfg
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.12.2004, 12:23 Uhr
RHBaum



Allgemein :

Die funktion / der Block, der deine Strukt allokiert, sollt sie auch wieder freigeben .....

Fuer deine Frage lauten dann die Antworten, 1. ja 2. nein :-)

Mann sollte nie, nie, nie, Speicher allokieren und den per rueckgabewert zurueckgeben ....
(Es gibt jetzt sicher einige, die Beispiele bringen wo es moeglich waere, aber man sollt es sich gar ned erst angewoehnen)

In deinem konkreten Fall :

Du brauchst die Struktur nur einmal (kein feld) warum die dynamische allokation ?

Lass deinen Anwender den Speicher allokieren .....



Code:

long DatenSchreiben(WORD Index,struct DATEN * pdata)
{
    if(pdata)
    {
        // hier nu in deine Strukt schreiben lassen
    }
}



Hat den vorteil, das dein User der funktion selber entscheidet, ob die daten aufn stack (performance) oder dynamisch anglegt werden ....


Code:

    // irgendwo im code
    // statische Version
    struct DATEN  data;

    long lreturn = DatenSchreiben(4,&data);

    // Dynamische version
    struct DATEN * pdata;
    pdata=(struct DATEN *)malloc(sizeof(struct DATEN));
    long lreturn = DatenSchreiben(4,pdata);
    free(pdata);



Aehnlich macht man es, wenn man die goresse des Speichers ausserhalb der funktion nicht weiss, dann allokiert man in der funktion auch ned selber einfach drauf los, sondern macht 2 versionen der Funktion ... einmal wo man den speicherbedarf ermitteln kann, einmal wo man den Speicher beschreibt ....

Am beispiel einer funktion die nen string unbekannter Laenge liefert .... sollte es ungefaehr so aussehen

Code:

long GetString(int * ilength,char * pdata)
{
     // implementation ueberlass ich dir :-)
}



Verwendung:

Code:

    // wenn man bei dem datenwert nen nullzeiger uebergibt als (zieladresse, sollte die funktion nur die laenge ermitteln !!!
    int ilen = 0;
    long lreturn = GetString(&ilen,0); // laenge

    // mit der Laenge koennen wir nun den speicher allokieren !
    char * strbuffer = (char *)malloc(sizeof(char) * ilen);
    // nun die funktion den String zurueckgeben lassen
    lreturn = GetString(&ilen,strbuffer);
    // irgendwann wieder freigeben
    free(strbuffer);



Prinzip verstanden ?
So manchen es zumindest die meisten c-Funktionen aus diversen libs ....

Ciao ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
03.12.2004, 15:40 Uhr
~_Michael_
Gast


Vielen Dank für die guten ausführlichen Antworten!!


Was ich eigentlich zur Zeit versuche, ist eine Warteschlange zu bauen. Diese Warteschlange soll nach dem FIFO- Prinzip gefüllt und gelesen werden. Dabei muss sich natürlich die Länge der Schlange auch dynamisch verlängern und verkürzen. Dabei arbeite ich mit rekursiven Strukturen und dazu muss ich ja auch dynamisch Speicher anfordern und auch wieder freigeben.

Hab mich wohl irgendwo verloren...

Das war eigentlich der ganze Hintergrund. Ich werde wohl noch einmal mein Buch aus der Ecke holen und ein paar Zeilen lesen

Vielen Dank

Michael
 
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: