Benutzen einer deque...



  • Hallo,

    ich habe in meinem Projekt eine Klasse "PicFrame", und Instanzen von dieser möchte ich gerne in eine deque packen. Genauer gesagt, Pointer auf Instanzen davon.

    Die Klasse PicFrame hat den Konstruktor

    PicFrame::PicFrame(CString pathName)
    

    Ich habe das Ganze also so versucht:

    static std::deque<CString> m_picPathNames;
    static std::deque<PicFrame *> m_picFrames;
    
    //... an dieser Stelle werden die PfadNamen in m_picPathNames lesen
    
    	for(int i=0;i<filecount;i++){
    		CString path = m_picPathNames.at(i);
    
    		m_picFrames.push_back(new PicFrame(path));
    
    	}
    

    Dies läuft in einer Statischen Klasse "FrameList" ab.

    soweit, so gut (oder schlecht) - wenn ich mein Programm in Visual Studio beende, dann dauert das erst einmal eine halbe Ewigkeit, bis der Debugger ausgeht, und zwar durch diese Meldungen:

    Detected memory leaks!
    Dumping objects ->
    {3646} normal block at 0x059B4078, 8 bytes long.
     Data: < pY     > 18 70 59 00 CD CD CD CD 
    {3633} normal block at 0x059B3FE0, 8 bytes long.
     Data: < pY     > 18 70 59 00 CD CD CD CD 
    (...)
    

    also, ich hab wohl was nicht so ganz verstanden was die speicherverwaltung angeht. aber was? kann mir jemand auf die sprünge helfen?
    ich dachte, ich instanziiere mit "new PicFrame" ein Objekt, und packe dann einen Pointer darauf in meine deque. Warum klappt das nicht, und vor allem, wie kriege ich das dann hin?

    Danke schonmal für Noob-Hilfe...



  • zu jedem new gehört auch ein delete.



  • ich dachte, dann wäre die instanz nicht mehr in der deque enthalten!?

    Ich dachte ich habe folgendes zu tun:

    1. deque mit objekten füllen
    2. mit den objekten arbeiten
    3. zum Schluss ein cleanup, das die objekte löscht

    ?



  • Richtig erkannt - nur wo hast du in deinem Programm Schritt 3 eingebaut?

    (der Destruktor der deque löscht nur die elemente selber, aber nicht den Speicherbereich, auf den sie zeigen - dafür bist du zuständig)



  • das habe ich im destruktor meiner form, in der das ganze liegt - habe ich im Posting aus Gründen der Vereinfachung nicht aufgeführt.

    void FrameList::cleanUp(){
    	for(int i=0;i<(int)m_picFrames.size();i++){
    		PicFrame* pcfr = m_picFrames.at(i);
    		delete pcfr;
    	}
    }
    

    EDIT: Es ist zu früh. Ewiges probieren, aber ich habe nicht gemerkt, dass das cleanup auskommentiert war 😑

    Danke, wenigstens hat mich das Posting drauf gebracht!



  • Hast du sonst noch irgendwo new? Vielleicht in PicFrame selbst?



  • Das ist aber nicht der Destruktor (der Destruktor heißt "FrameList::~Framelist()") 😉 Bist du sicher, daß dein Programm dort überhaupt reingeht?



  • siehe oben 😉

    EDIT: Es ist zu früh. Ewiges probieren, aber ich habe nicht gemerkt, dass das cleanup auskommentiert war 😑

    nein, das ist natürlich nicht der Destruktor. Das ist die Funktion, die im Destruktor der Framelist und dem Destruktor der Form aufgerufen wird (mittlerweile) 🙂



  • Hmm, jetzt habe ich ein anderes Problem mit der deque.

    ich liste also meine Dateien auf

    for(int i=0;i<filecount;i++){
    		CString path = m_picPathNames.at(i);
    		PicFrame* pcfr = new PicFrame(path);
    		m_picFrames.push_back(pcfr);
    
    		std::ostringstream oss;
    		oss << "Pfad hinzu: " << m_picFrames.back()->getPathName();
    		writeDebug(oss);
    	}
    

    in meinem Debugfenster (writeDebug schreibt dort heraus) erscheint:

    Pfad hinzu: C:\Temp\ive10000226.tiff
    Pfad hinzu: C:\Temp\ive10000227.tiff
    Pfad hinzu: C:\Temp\ive10000228.tiff
    Pfad hinzu: C:\Temp\ive10000229.tiff
    (...)
    

    ich lese einen Frame aus:

    PicFrame* pcfr = FrameList::getPicFrameAt(146);
    	std::ostringstream oss;
    	oss << "Frame: " << pcfr->getPathName();
    	writeDebug(oss);
    

    getPicFrameAt(int i):

    PicFrame* FrameList::getPicFrameAt(int i){
    
    	std::ostringstream oss;
    	oss << "getFrameAt: " << i << " Framecount: " << filecount;
    	writeDebug(oss);
    
    	if(!(i >= filecount) && (!i<0))){
    		oss.clear();
    		oss << "Return: " << m_picFrames.at(i)->getPathName();
    		writeDebug(oss);
    		return m_picFrames.at(i);
    	}
    	else 
    		return m_picFrames.back();	
    }
    

    Die Ausgabe in meinem Debugfenster:

    getFrameAt: 146 Framecount: 226
    Return: C:\Temp\ive10000451.tiff
    

    ich bekomme immer die Datei C:\Temp\ive10000451.tiff zurück..

    wenn das jetzt auch so einfach ist, dann lasse ich mich hier nur noch unter anderem Namen blicken 😞

    EDIT: mit debuggen habe ich jetzt herausgefunden, dass nach jedem hinzufügen eines neuen objektes die pointer offensichtlich alle auf dasselbe objekt zeigen.
    sobald ich ein neues hinzugefügt habe, bekomme ich mit getFrameAt(int i) nur noch das letzte objekt, egal welchen index ich angebe..



  • Hat überhaupt jedes PicFrame-Objekt einen eigenen CString mit dem jeweiligen Pfadnamen? Oder speicherst du dort lediglich eine Referenz/Zeiger auf den Parameter, den du im Konstruktor bekommen hast?

    (die Ausgabe deutet auf letzteres hin)



  • anscheinend hast du recht.

    ich hatte in meiner PicFrame.cpp die variable PathName deklariert. Jetzt habe ich sie in die PicFrame.h ausgelagert, und es geht. Kannst Du mir das erklären?



  • Wenn du eine globale Variable "PathName" hast, kannst du dort wieviele Dateinamen unterbringen? (richtig - die Antwort lautet "genau einen")

    Korrekterweise gehört die Variable PathName in die Deklaration der PicFrame-Klasse, dann gilt sie als Member der Klasse und jedes PicFrame bekommt eine eigene Version davon, in der der jeweils eigene Dateiname eingetragen werden kann:

    class PicFrame
    {
    public:
      PicFrame(const CString& name) : m_path(name) {}
      ...
    private:
      CString m_path;
      ...
    };
    


  • aaah okay, danke!


Anmelden zum Antworten