Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

1

25.11.2009, 20:29

Meyers-singleton instanz wird nicht freigegeben?

Der Titel sagt schon alles. Ich habe einen Meyers-Singleton für meine Log-Klasse, aber der destruktor wird nicht aufgerufen! Das ist doch eigentlich zeimlich eigenartig...
Was mir aufgefallen ist, dass wenn bei mir speicher auf dem heap freigegeben wird, aber das halt ein zweites mal passiert auf grund von kopierten zeigern (ich baue grade aus diesem grund reference counting ein), ist bei mir sofort der raussprung aus dem programm.
Hat wer eine idee, wie ich da am cleversten vorgehe, um da hinweise zu finden?!

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

25.11.2009, 20:41

Was meinst du mit Heap Speicher? Das Meyers Singleton ist ja besonders, dass es eben ohne den zurecht kommt.. Du kannst den auch nicht vorzeitig zerstören, da er ja auf einer statischen Variable basiert..

Ansonsten: Wie kommst du drauf, dass er nicht freigegeben wird?

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

3

25.11.2009, 20:50

nope nicht der meyes singleton an sich. ich meine wenn ich ein anderes objekt per delete lösche, wo ich woanders noch eionen zeiger drauf habe und dann nochmal freigebe, frage ist. und da ist mir beim debuggen aufgefallen, dass danach das debuggen beendet wird, also das programm beendet wird.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

4

25.11.2009, 21:07

Undefiniertes Verhalten? - Warum sollte das Programm nicht beendet werden, wenn du etwas nicht erlaubtes machst? (Also das freigeben von Speicher, welcher bereits freigegeben ist.)

Aber ich verstehe immer noch nicht, was jetzt das Meyers Singleton damit zu tun hat?

5

25.11.2009, 21:07

Zitat von »"TrommlBomml"«

ich meine wenn ich ein anderes objekt per delete lösche, wo ich woanders noch eionen zeiger drauf habe und dann nochmal freigebe, frage ist.
Wie wärs mit ganzen Sätzen?

Natürlich darfst du den selben Speicherbereich nicht zwei Mal freigeben, das ruft undefiniertes Verhalten hervor. Kannst du etwas deutlicher werden, eventuell durch kurzen, das Problem beschreibenden Code?

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

6

25.11.2009, 21:12

Zitat von »"Nexus"«

Zitat von »"TrommlBomml"«

ich meine wenn ich ein anderes objekt per delete lösche, wo ich woanders noch eionen zeiger drauf habe und dann nochmal freigebe, frage ist.
Wie wärs mit ganzen Sätzen?

:evil:
Das muss ich dir leider auch ankreiden Tromml. Bitte gib dir beim schreiben ein wenig mehr Mühe. Ich kann kaum verstehen, was du da schreibst. (und das liegt nicht an deinem Berliner Akzent. :p)

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

7

25.11.2009, 21:27

ja asche auf mein haupt, sry leuts.

also es geht einfach darum, dass ich beim debuggen festgestellt habe, dass der destruktor folgender klasse nicht aufgerufen wird (auf das wesentliche reduziert):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class CLogFile
{
private:

        std::ofstream   m_osFile;

private:

    CLogFile()
    {
        m_osFile.open("log.txt",std::ios::out);
            AddLog("The Drum Machine - Log File");
            AddLog("Begin Logging...");
    }

    CLogFile(const CLogFile &oCopy);
    CLogFile operator=(const CLogFile &oAssign);

public:

    static CLogFile &GetInstance()
    {
        static CLogFile oLogFile;
        return oLogFile;
    }

    ~CLogFile()
    {
        AddLog("End Logging.");
            m_osFile.close();
    }
};


und dort wird halt der destruktor nicht augerufen (zumindest erreicht er den breakpoint nicht). natürlich rufe ich mindestens einmal GetInstance() auf...

ansonsten ist mir halt nur aufgefallen, dass ich halt undefiniertes verhalten anscheinened provoziere, weil ich vertexbuffer über mehrere objekte teile indem ich zeiger kopiere. ja ich weiss ist nicht schön, wird ja behoben, mir gehts nur darum, ob das der fehler sein kann:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
//ein objekt erzeugt einen vertexbuffer

CVertexBuffer *pVB = new CVertexBuffer(...);

//und ein anderes objekt braucht diesen vertexbuffer auch, weil es dasselbe 3d-modell repräsentiert.

CVertexBuffer *pVB2 = pVB;

delete pVB;
delete pVB2;


kann das durchaus das problem sein durch dieses undefinierte verhalten und damit auch das nicht freigeben von singleton-objekten? ich habe es nur auf dieses beispiel bezogen, es gibt eventuell andere stellen im code, wo das mit anderen objekten und anderen zeigern passiert.

hoffe jetzt war es verständlich...

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

8

25.11.2009, 21:37

Dann mach da halt mal nur ein delete hin. Dann ist das ja wieder erlaubt, obwohl, wenn da kein Zusammenhang besteht sollte es kein Einfluss haben (auch wenn es durchaus möglich ist).

Also hat ja dein Vertexbuffer ja mal nix mit dem Singleton zu tun, oder?

Du kannst ja mal in einem leeren Projekt einfach einmal die Log Klasse instanzieren und dann siehst du ja recht gut, ob es immer noch ein Problem gibt.

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

9

26.11.2009, 09:56

im prinzip war es die lösung, nur an einer stelle die man wie immer nicht vermutet. jetzt funktioniert es wieder. ich hab eine klasse CReferenceWatcher, der alle reference-count objects überwacht und bei keiner referenzierung freigibt. abgeleitet ist das von CGenericHandleManager<NUMERICHANDLE,CLASS*>. und da wird im destruktor die interne std::map durchiteriert und alle CLASS* elemente gelöscht per delete. das mache ich aber in CReferenceWatcher schon vorher, aber ich leere die geerbte std::map nicht, wodurch ich dadurch doppelt freigebe (der ererbte destruktor macht das auch, weil alle anderen derivate nicht selber löschen im destruktor).

kurz und knapp: löft!

10

26.11.2009, 20:03

Zitat von »"TrommlBomml"«

ich hab eine klasse CReferenceWatcher, der alle reference-count objects überwacht und bei keiner referenzierung freigibt.
Wieso eigentlich das Rad neu erfinden, anstatt sich auf getestete und optimierte Mittel zu verlassen? boost::shared_ptr (gibts auch im TR1) hat die gleiche Funktion.

Zitat von »"TrommlBomml"«

abgeleitet ist das von CGenericHandleManager<NUMERICHANDLE,CLASS*>.
Brauchst du diese Vererbung tatsächlich (d.h. ist dein CReferenceWatcher wirklich ein CGenericHandleManager)? Sorry, falls ich daneben liege, aber Vererbung wird eben oft eingesetzt, wo Aggregation angebrachter wäre. Hier habe ich so einen Verdacht, aber kann gut sein, dass ich mich irre... ;)

Werbeanzeige