Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » delete richtig angewendet?

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 < [ 2 ]
000
05.03.2007, 19:44 Uhr
~tecs
Gast


Hallo,
es wäre schön, wenn jemand ma einen Blick auf die folgende Datenstruktur werfen könnte. Und mir dann sagen könnte, ob der dynamisch reservierte Speicher auch wieder
ordnungsgemäß freigegeben wird. Ich habe die Befürchtung, dass dies nicht der Fall ist.


C++:
class RTsys {
public:
    bool init_phase;
    DSsys *dssys;

  RTsys();  // constructor
  ~RTsys(); // deconstructor
};


RTsys::RTsys() {
    init_phase = true;
    dssys = NULL;
}

RTsys::~RTsys() {
  if(dssys)
      delete dssys;
}


class DSsys {
public:
    char* name;
    
    int num_actions;
    float* fwerte;
    int num_tilings;
    int memory_size;
    
    float* Q;
    float* theta;
    float* e;
    int** F;

    int* nonzero_traces;
    int* nonzero_traces_inverse;

  DSsys();  
  ~DSsys();
};

DSsys::DSsys() {
    name = "NoName";
    
    num_actions= 2;
    fwerte = NULL;
    num_tilings = 20;
    memory_size = 10000;

    Q = NULL;
    theta = NULL;                      
    e = NULL;                            
    F = NULL;            

    nonzero_traces = NULL;
    nonzero_traces_inverse = NULL;
}


DSsys::~DSsys() {
    if (name) delete[] name;

    if (Q){
        delete[] Q;
        //Q = NULL;
    }
    if (theta){
        delete[] theta;
        //theta=NULL;
    }
    if (e){
        delete[] e;
        //e=NULL;
    }
    if (F){
        for(int j =0; j < num_actions; j++)
            delete [] F[j];
        delete [] F;
        //F=NULL;
    }
    if (nonzero_traces)    {
        delete[] nonzero_traces;
        //nonzero_traces = NULL;
    }
    if (nonzero_traces_inverse)    {
        delete[] nonzero_traces_inverse;
        //nonzero_traces_inverse = NULL;
    }

    if (fwerte)    {
        delete[] fwerte;
        //fwerte = NULL;
    }
}


/*Initialisierung im Programmquellcode*/
RTsys* rtsys = new RTsys;
rtsys->dssys = new DSsys;
rtsys->dssys->fwerte = new float[rtsys->dssys->num_actions];
rtsys->dssys->Q = new float[rtsys->dssys->num_actions];
rtsys->dssys->theta = new float[rtsys->dssys->memory_size];
rtsys->dssys->e = new float[rtsys->dssys->memory_size];

rtsys->dssys->F = new int*[rtsys->dssys->num_actions];
    for (int i=0;i<rtsys->dssys->num_actions; i++)
        rtsys->dssys->F[i]=new int[rtsys->dssys->num_tilings];

rtsys->dssys->nonzero_traces = new int[rtsys->dssys->max_nonzero_traces];
rtsys->dssys->nonzero_traces_inverse = new int[rtsys->dssys->memory_size];

...

delete rtsys;



Vielen Dank.

Dieser Post wurde am 05.03.2007 um 21:15 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
05.03.2007, 21:16 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi,
teste das doch einfach mit valgrind
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
05.03.2007, 21:32 Uhr
~tecs
Gast


hi,
valgrind.. hmm ist eine Linux "Sache" (sorry soll nicht abwertend klingen)?
Leider bin ich einer von den Russisch Roulette Spielern und bin mit Windows unterwegs.
Also empfiehlt es ein entsprechendes Programm (Rational Purify for Windows?) zu nutzen. Okay. Danke für den Denkanstoss.

ps: Werde mir beim nächsten Mal besser die Editierfunktionen anschauen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
05.03.2007, 21:36 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi,
achja,

was mir so auffällt:


C++:
rtsys->dssys = new DSsys;



und das löschen im Destruktor -> unschön!

Entweder beides innerhalb der klasse, oder beides außerhalb (wär sauberer vom Design)

Außerdem natürlich der Zugriff auf die Member - in diesem Fall ists wahrscheinlich einfacher alles einfach über public-Variablen zu machen - sinnvoll ist aber meist trotzdem nur über Get/Set-Methoden die Variablen setzen/abfragen zu können, das erspart teilweise viel Fehlersuche.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
05.03.2007, 21:59 Uhr
~tecs
Gast


hi,
zum ersten Teil:

RTsys::~RTsys() {
if(dssys)
delete dssys;
}

ist unschön?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
05.03.2007, 22:15 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


ja,


C++:
RTsys::RTsys() {
    init_phase = true;
    dssys = new DSsys; // <-- hier so wärs vom design her dann ok
}

RTsys::~RTsys() {
  if(dssys)
      delete dssys;
}


--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
05.03.2007, 22:25 Uhr
~tecs
Gast


Okay, wird geändert. Und ich werde so ein Tool ma verwenden.
vielen Dank für deine Antworten
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
05.03.2007, 22:43 Uhr
0xdeadbeef
Gott
(Operator)


Das if(dssys) ist da übrigens überflüssig, delete NULL; macht nichts. Ansonsten würde ich empfehlen, mal in die Standardbibliothek zu kucken, insbesondere std::string und std::vector könnten da hilfreich sein. Auch frage ich mich, warum RTSys::dtsys auf dem Heap liegen muss, und alles public zu machen scheint mir doch etwas fragwürdig - wir schreiben ja nun kein C mehr, oder?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
06.03.2007, 09:58 Uhr
ao

(Operator)


Der Sinn der Kapselung ist, dass die Klasse ihre inneren Datenstrukturen selber anlegt und verwaltet und dass das nicht im äußeren Programmcode geschieht.

So wie du es gemacht hast, ist die Klasse ein offener Container, der seine Arbeitsmittel von außen untergeschoben kriegt und irgendwie damit klarkommen muss.

Dieses ganze Zeug gehört in den Konstruktor von DSSys:

C++:
rtsys->dssys->Q = new float[rtsys->dssys->num_actions];
rtsys->dssys->theta = new float[rtsys->dssys->memory_size];
rtsys->dssys->e = new float[rtsys->dssys->memory_size];

rtsys->dssys->F = new int*[rtsys->dssys->num_actions];
    for (int i=0;i<rtsys->dssys->num_actions; i++)
        rtsys->dssys->F[i]=new int[rtsys->dssys->num_tilings];

rtsys->dssys->nonzero_traces = new int[rtsys->dssys->max_nonzero_traces];
rtsys->dssys->nonzero_traces_inverse = new int[rtsys->dssys->memory_size];



Gruß,
ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
06.03.2007, 13:37 Uhr
~tecs
Gast


Okay, um das Bild einbisschen zu schärfen:
Die Initialisierung im Programmquellcode hätte momentan folgende Struktur


C++:
//Start
RTsys* rtsys = new RTsys;
...
rtsys->init_phase=true;
...
//Abfrage, ob DSsys verwendet wird oder nicht.
if (rtsys->init_phase)
{
    rtsys->dssys = new DSsys;
}

//Init (Beispielsweise aus einer Konfigdatei)
//Dynamische Übergabe der Anzahl der Aktionen
rtsys->dssys->num_action=3;
//weitere Konfigurationsmöglichkeiten sollen am Beginn möglich sein
//darunter fallen etwa das Festlegen der Anzahl der Tilings oder die Mem-Größe
...
if (rtsys->init_phase)
{
    rtsys->dssys->fwerte = new float[rtsys->dssys->num_actions];
    rtsys->dssys->Q = new float[rtsys->dssys->num_actions];
    rtsys->dssys->theta = new float[rtsys->dssys->memory_size];
    rtsys->dssys->e = new float[rtsys->dssys->memory_size];

    rtsys->dssys->F = new int*[rtsys->dssys->num_actions];
        for (int i=0;i<rtsys->dssys->num_actions; i++)
            rtsys->dssys->F[i]=new int[rtsys->dssys->num_tilings];

    rtsys->dssys->nonzero_traces = new int[rtsys->dssys->max_nonzero_traces];
    rtsys->dssys->nonzero_traces_inverse = new int[rtsys->dssys->memory_size];
}


//Ende
delete rtsys;

/*------------*/



@FloSoft:

C++:
RTsys::RTsys() {
    init_phase = true;
    dssys = new DSsys; // <-- hier so wärs vom design her dann ok
}

RTsys::~RTsys() {
  if(dssys)
      delete dssys;
}


jupp. Aber wäre das notwendig, wenn man noch nicht weiss, ob man dssys überhaupt benötigt!?

@0xdeadbeef:
> Das if(dssys) ist da übrigens überflüssig, delete NULL; macht nichts.
Das mit if(**) sehe ich häufig in verschiedenen Quellcodes... habe es deswegen so übernommen.
Und warum setzt man einen Zeiger nach dessen Löschung auf NULL?

> Auch frage ich mich, warum RTSys::dtsys auf dem Heap liegen muss,..
Bei der Arbeit mit den C/C++ S-Funktionen unter MATLAB/Simulink stellte sich in meinen Fall (sicherlich auch bedingt durch
fehlendes "Wo steht das genau beschrieben"-Wissen) diese Notwendigkeit heraus. Es geht dabei vorallem um das Verwalten und Setzen von globalen Variablen im Zusammenspiel
zwischen dem Matlab Workspace, der Simulationsumgebung und den verwendeten C/C++ Funktionen. Also wenn sich zufällig damit jemand auskennt... - ich weiss falsches forum
Mir gehts vorallem darum, dass die Strukturen stimmig sind, und ich nicht großartig gegen Konventionen etc. verstosse bzw. neue Denkanstösse bekomme
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ 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: