Pointer-Array von struct, die stl::map enthält - Verwendung



  • Hallo,
    ich habe einigen Quellcode von meinem Vorgänger geerbt.
    Dort musste ich einige Perfomance Verbesserungen ergänzen,
    was auch in einem Fall der Verwendung gut funktioniert.
    Im anderen Fall führt es leider irgend wann zum Absturz.

    Der Fall ist folgender:
    Ich habe eine struct um zwei maps ergänzt, um Sortierung und Zugriff zu beschleunigen.
    Ich habe das zum Testen in ein kleines Dialog-Programm reingesetzt.
    Daraus der Auszug aus dem Quellcode.

    Diese struct ist nun zudem noch als Pointer deklariert (wie unten zu sehen).
    Mit diesem Pointer-Typ wird dann im Programm ein Array dieser Struct mit
    dem new-Operator angelegt. Auch wird im Destructor der Klasse ein delete
    ausgeführt.

    Meine Frage:
    Wie muss ich das ergänzen, damit ich auch meine maps in der Pointer-Struct
    erzeugen und wieder bereinigen kann?
    Wahrscheinlich muss ich die Operatoren definieren, oder so? Aber wie?
    Könnt ihr mir bitte helfen.

    Deklaration im .h-File:
    --------------------------------

    typedef struct _FileListe {
    	std::multimap <CString, CString> m_FileListDateSort;
    	std::map <CString, DWORD> m_FileListFileSort;
    	CString*				m_pFiles;			 
    	DWORD					m_dwNoOf;
    } FILELISTE,*PFILELISTE;
    
    // CTestComboDlg Dialogfeld
    class CTestComboDlg : public CDialog
    {
    // Konstruktion
    public:
    	CTestComboDlg(CWnd* pParent = NULL);
    	~CTestComboDlg();
    
    	PFILELISTE	m_pPrgFileListe;
    
    //.....
    }
    

    im .cpp-File:
    --------------------------------------

    CTestComboDlg::CTestComboDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CTestComboDlg::IDD, pParent)
    {
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    
    	m_pPrgFileListe = new FILELISTE[10];
    	ZeroMemory(m_pPrgFileListe,sizeof(FILELISTE)*10);
    
    	for(DWORD n=0;n<10;n++) {
    		m_pPrgFileListe[n].m_dwNoOf = 5;
    		m_pPrgFileListe[n].m_pFiles = new CString[m_pPrgFileListe[n].m_dwNoOf];
    	}
    // Hier drin funktioniert noch alles. ICh verwende die maps nicht.
    // Allerdings gehts nicht, wenn ich versuche in das mit new erzeugte Pointer-Struct in die maps zu schreiben.
    
    }
    
    CTestComboDlg::~CTestComboDlg()
    {
    	if(m_pPrgFileListe) {
    		for(DWORD n=0;n<10;n++) {
    			if(m_pPrgFileListe[n].m_pFiles){
    				delete[] m_pPrgFileListe[n].m_pFiles;
    //				delete[] m_pPrgFileListe[n].m_FileListDateSort; // Das kompiliert schon nicht!
    //				delete[] m_pPrgFileListe[n].m_FileListFileSort; // Das kompiliert schon nicht!
    			}
    		}
    		delete[] m_pPrgFileListe; // hier stürzt es ab!
    	}
    // natürlich muss ich auch die in der map enthaltenen elemente bereinigen.
    // aber die sind momentan eh leer.
    }
    


  • Der Code ist furchtbar, aber was will man machen, wenn man so etwas erbt.

    Das konkrete Problem ist hier das ZeroMemory. Das zerlegt dir die Maps. Freigeben musst du übrigens weder die Maps noch die Elemente darin.



  • MFK schrieb:

    Der Code ist furchtbar, aber was will man machen, wenn man so etwas erbt.

    Das konkrete Problem ist hier das ZeroMemory. Das zerlegt dir die Maps. Freigeben musst du übrigens weder die Maps noch die Elemente darin.

    Hallo MFK,
    vielen Dank für Deine Anmerkung.
    Der Absturz hatte wirklich was mit dem ZeroMemory zu tun.
    Ich habe es rausgenommen. Aber nun stürzt mir das Programm ab,
    wenn ich den Speicher des in der struct enthaltenen CString* Arrays
    freigeben will.

    Der Debugger sagt mir jedenfalls, dass ich Memory Leaks bekomme,
    wenn ich das nicht tue, genauso, wie für die Struct selbst.

    Ich muss mich nun anscheinend entscheiden, ob ich

    delete[] m_pPrgFileListe;
    oder
    delete[] m_pPrgFileListe[n].m_pFiles;

    anwende. Memory Leaks bleiben aber.



  • Kannst du m_pFiles nicht durch nen std::vector<CString> ersetzen?
    Und m_pPrgFileListe dann zu nem std::vector<FILELISTE> umbauen?
    Dann brauchst du überhaupt kein new und kein delete mehr.



  • hustbaer schrieb:

    Kannst du m_pFiles nicht durch nen std::vector<CString> ersetzen?
    Und m_pPrgFileListe dann zu nem std::vector<FILELISTE> umbauen?
    Dann brauchst du überhaupt kein new und kein delete mehr.

    Vielen Dank hustbaer für den Hinweis.
    Das wäre sicher die bessere Lösung.
    Die Änderungen sind damit sicherlich einiges aufwendiger.
    Mein Ziel war zunächst der Performance-Fix durch die beiden zusätzlichen Maps.
    Das war an einer Stelle und einer Anwendungsvariante.
    Musste insgesamt 10 Zeilen an 2 Stellen anpassen.
    Aber es wird noch an einigen Stellen mehr gebraucht.

    Ich habe es aber vorerst gelöst.
    Das mit dem ZeroMemory war schon ein guter Hinweis!
    Aus der Struct habe ich eine eigene Klasse gemacht, mit eigenem Destructor.
    Das hat die verbleibende Logik auch kaum beeinflusst.
    Das ZeroMemory hatte mir leere CString* Arrays in einigen der Strukt verdeckt.
    Daher rührte der neue Fehler. Das frage ich nun vorher ab.


Anmelden zum Antworten