Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » woher kommt das Memoryleak? - (shared_ptr)

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
01.08.2009, 12:05 Uhr
deer



Ich habe eine polymorphe Klassenhierarchie. Durch den Gebrauch von valgrind habe ich entdeckt, dass ich durch (1) ein Memoryleak kriege.

Ich habe das Gefühl, dass ich etwas Grundlegendes übersehen habe!? Any ideas?

Vielen Dank!



C++:
#include <boost/shared_ptr.hpp>
#include <unordered_map>
#include <string>
#include <stdio.h>
using std::string;
using boost::shared_ptr;

class Symbol {
public:
   shared_ptr<Symbol> type;
   string name;
   Symbol() {}
   Symbol(string s, shared_ptr< Symbol > t) : name(s), type(t) {}
   virtual ~Symbol() { }
};

class VarSym: public Symbol {
public:
    VarSym(string s, shared_ptr< Symbol > type) :Symbol(s, type) {}
};
    
typedef std::unordered_map<string, shared_ptr<Symbol>> symMap;
typedef shared_ptr<Symbol> SymPtr;
    

class Scope {
public:
     Scope *parent;
     Scope()  : parent(0){}
     Scope(Scope* p) : parent(p) {}
     virtual ~Scope() {}
     virtual void define(string name, shared_ptr<Symbol>  s) = 0;
};

class SymbolWithScope : public Symbol , public Scope{
public:
    symMap symbols;  

     SymbolWithScope(Scope* p)  : Scope(p) {}
     SymbolWithScope(string s, shared_ptr< Symbol > type) : Symbol(s, type) {}
     virtual ~SymbolWithScope() { symbols.clear(); }
     virtual void define(string name, shared_ptr<Symbol>  s)
     {
         symbols.insert(std::make_pair(name, s));
     }
};

class LocalScope : public SymbolWithScope {
public:
     LocalScope(Scope* p) : SymbolWithScope(p) {}
     ~LocalScope() {}
};

// global scope
Scope *scp = new LocalScope(0);

template <typename T>
void storeNewSymbol(string ident, shared_ptr<T> symbol)
{
    scp->define(ident, symbol);
}

int main()
{
    printf("scp: %p\n", scp);
    string identifier("ident1");
    shared_ptr<SymbolWithScope> currentScope(new LocalScope(scp));
    storeNewSymbol(identifier, currentScope);
    
    scp = currentScope.get(); // (1) mem. leak
    delete scp;
}


 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
01.08.2009, 12:23 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja du hast ein new aber kein delete:


C++:
Scope *scp = new LocalScope(0);

// ...

scp = ...; // mem leak


--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
01.08.2009, 12:30 Uhr
deer




Zitat von FloSoft:
naja du hast ein new aber kein delete:


C++:
Scope *scp = new LocalScope(0);

// ...

scp = ...; // mem leak




doch habe ich:


C++:
int main()
{
  ...
  delete scp;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
01.08.2009, 12:59 Uhr
TOSHMAX



Du hast zwei new aber nur ein delete:

C++:
Scope *scp = new LocalScope(0); // new 1
...
shared_ptr<SymbolWithScope> currentScope(new LocalScope(scp)); // new 2

...
delete scp; // delete 1

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
01.08.2009, 13:11 Uhr
deer




Zitat von TOSHMAX:
Du hast zwei new aber nur ein delete:

C++:
Scope *scp = new LocalScope(0); // new 1
...
shared_ptr<SymbolWithScope> currentScope(new LocalScope(scp)); // new 2

...
delete scp; // delete 1




oh richtig! sorry.
aber wo müsste ich es löschen? ich weise dem parent das neue objekt nur zu:

C++:
Scope(Scope* p) : parent(p) {}


ich nehme an, ich müsste das 2. objekt, das ich mit new alloziere, im destructor zerstören.
da die Klasse Scope abstrakt ist, kriege ich ein segmentation fault wenn ich parent im dtor (von SymbolWithScope) löschen will.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
01.08.2009, 13:42 Uhr
TOSHMAX



Du musst das 1. Objekt vor dieser Zeile löschen:

C++:
scp = currentScope.get();


Denn danach zeigt der Pointer nicht mehr auf das 1. Objekt und du kannst nicht mehr darauf zugreifen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
01.08.2009, 15:28 Uhr
FloSoft
Medialer Over-Flow
(Administrator)



Zitat von TOSHMAX:
Du musst das 1. Objekt vor dieser Zeile löschen:

C++:
scp = currentScope.get();


Denn danach zeigt der Pointer nicht mehr auf das 1. Objekt und du kannst nicht mehr darauf zugreifen.

darum meldet er ja da an der stelle auch das memory leak (wie ich bereits sagte)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
01.08.2009, 15:58 Uhr
0xdeadbeef
Gott
(Operator)



C++:
shared_ptr<Scope> scp = new LocalScope(0);


? Und entsprechend in SymbolWithScope dafür sorgen, dass der Kram sharable ist. Alternativ:

C++:
LocalScope start_scope(0);
Scope *scp = &start_scope;



Eigentlich empfiehlt sich natürlich sowieso, den Status vernünftig in einer Klasse zu kapseln und in deren Destruktor aufzuräumen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 01.08.2009 um 16:09 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
02.08.2009, 20:16 Uhr
deer




Zitat von 0xdeadbeef:

C++:
shared_ptr<Scope> scp = new LocalScope(0);


? Und entsprechend in SymbolWithScope dafür sorgen, dass der Kram sharable ist. Alternativ:

C++:
LocalScope start_scope(0);
Scope *scp = &start_scope;



Eigentlich empfiehlt sich natürlich sowieso, den Status vernünftig in einer Klasse zu kapseln und in deren Destruktor aufzuräumen.


Erstmals vielen Dank für alle Inputs! Ich habe diese Lösung ausprobiert:

C++:
LocalScope start_scope(0);
Scope *scp = &start_scope;


Aber im ersten Anlauf hat es nicht funktioniert... Der letzte Kommentar: "den Status vernünftig in einer Klasse zu kapseln" macht mehr Sinn, da ich ein vernünftiges design bevorzuge.
Könntest du das noch etwas erläutern? Das Problem ist, dass ich die scopes nicht zerstören kann (bis ganz am Schluss) da ich sie für den lookup von variablen noch brauche.

Danke für jeden Input...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
02.08.2009, 21:51 Uhr
0xdeadbeef
Gott
(Operator)


Welche Modellierung am sinnvollsten ist, hängt davon ab, was du eigentlich modellierst. Wenn ich richtig verstehe, was du da vorhast, scheint es mir am sinnvollsten, die ganze Maschine in einer Klasse zu kapseln und darin zu rechnen, also etwa:

C++:
class state_machine {
public:
  state_machine();

  void start();
  void store_symbol(string ident, shared_ptr<T> symbol);

private:
  LocalScope top_scope;
  Scope *current_scope;
};

state_machine::state_machine()
  : top_scope(0), current_scope(top_scope) { }

// ...

int main() {
  state_machine my_machine;

  my_machine.start();
}


Allerdings bin ich mir nicht wirklich sicher, ob ich verstehe, was du eigentlich beabsichtigst, denn wenn es um das geht, worum ich es vermute, wären Symbole und Scopes völlig verschiedene Entitäten und die SymbolWithScope-Klasse ergäbe in der vorhandenen Form (von Scope abgeleitet) wenig Sinn.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
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: