Problem mit std::map



  • Hallo.

    Mein Programm besteht aus 3 Dateien. Zum Problem komme ich am Ende. ^^

    Main.cpp

    case WM_INITDIALOG:
    {
    
            CAccountProfile* pAccounts	= new CAccountProfile
    
             if(!pAccounts->LoadAccounts(szAccountPath, hWnd) )
    	 {
    		 ::MessageBox(NULL, ("Failed to load Accounts!"), ("OnLoad"), NULL);
    		 PostQuitMessage(0);
    	 }
    
            break;
    }
    // ...
    case CBN_SELCHANGE:
    {
            pAccounts->UpdateAccount(hWnd); // soll die gui updaten
            break;
    
    }
    

    Gleich sind wir beim problem angekommen. @_@

    Profile.h

    // ....
    
    class CAccountProfile
    {
    public:
    
    typedef struct _ACCOUNT_INFO
    {
    	char AccLogin[128];
    	char AccPassword[128];
    	char AccServer[128];
    	char AccSlot[128];
    
    } ACCOUNT_INFO;
    
    public:
    
    	CAccountProfile(
    		void
    		);
    
    	virtual
    	~CAccountProfile(
    		void
    		);
    
    	bool LoadAccounts(
    		const char* pAccountPath,
    		HWND hWnd);
    
    	void UpdateAccount(HWND 
    		hWnd);
    
    	bool Deinitialize(
    		void
    		);
    
    private:
    
    	std::map<
    		std::string, ACCOUNT_INFO*> accountData;
    
    // ..
    

    Ahh! Endlich beim problem angekommen.

    Profile.cpp

    bool CAccountProfile::LoadAccounts(const char *pAccountPath, HWND hWnd)
    {
         ACCOUNT_INFO* pAccInfo = new ACCOUNT_INFO;
        // durch Textdatei durchwühlen und dann zur Map hinzufügen.
        this->accountData.insert ( std :: make_pair( accRemark, pAccInfo  ) );
        return true;
    }
    void CAccountProfile::UpdateAccount(HWND hWnd)
    {
                              LRESULT changed;
                              std::string chan;
    
    			  changed = SendMessage(GetDlgItem(hWnd, cmbAccProfile), CB_GETCURSEL, 0, 0);
    
    			  char tmp[128] = {0};
    		          SendMessage(GetDlgItem(hWnd, cmbAccProfile), CB_GETLBTEXT, changed, (LPARAM)tmp);
    			  chan = tmp;
                              std::map<std::string, ACCOUNT_INFO*>::iterator itr = this->accountData.begin();
    
                              while(itr != this->accountData.end()) // hier kratzt er immer ab.
                              {
                                   itr++;
                              }		
    }
    

    Das problem ist, dass es Immer abstürzt sobald UpdateAccount ausgeführt wird, bzw der while loop. Auch wenn sich garnichts in der Map befindet passiert es, bin für jede ratschläge offen.

    Grüße 🙂



  • An der iterierenden Schleife kann ich auf Anhieb keinen Fehler erkennen und an dem unformatierten restlichen Code habe ich kaum Interesse.
    Hast du mal den Debugger zu der Angelegenheit befragt?



  • Srry. Wusste nicht das man hier den "Nachrichtentext" größer machen kann, daher so unordentlich. Nein habe ich noch nicht, aber kann ich später oder morgen mal machen, danke dennoch.



  • das hier wird dein problem zwar nicht beheben aber vll wird dein quelltext damit ein wenig übersichtlicher:

    bier schrieb:

    Main.cpp

    case WM_INITDIALOG:
    {
          CAccountProfile* pAccounts	= new CAccountProfile
          if (! pAccounts->LoadAccounts(szAccountPath, hWnd))
          { //richtig eingerückt
                ::MessageBox (NULL, "Failed to load Accounts!", "OnLoad", NULL); //überflüssige Klammern gelöscht
                PostQuitMessage(0);
          }
    
          break;
    }
    // ...
    case CBN_SELCHANGE:
    {
          pAccounts->UpdateAccount (hWnd); // soll die gui updaten
          break;
    }
    

    Profile.h

    /* .... */
    
    class CAccountProfile
    {
    public:
    
    struct ACCOUNT_INFO
    {
    	char AccLogin[128];
    	char AccPassword[128];
    	char AccServer[128];
    	char AccSlot[128];
    }; //typedef struct ist unnötig - aber warum nimmst du kein std::string ?
    //mit std::string::c_str() bekommste genau so gut nen const char* und die restlichen Operationen (zeichenketten verknüpfen etc) sind viel einfacher zu handhaben
    //und wahrscheinlich (was aber keine rolle spielt) auch performanter als das char gefrickel
    
    	CAccountProfile (); //void in der parameterliste zu schreiben ist in C++ eher unüblich - wird vielerorts auch als schlechter Stil angesehen
    
    	virtual ~CAccountProfile ();
    
    	bool LoadAccounts (char* pAccountPath, HWND hWnd); //hWnd halte ich auch für keinen guten variablen-name
    //char* pAccountPath sollte ein std::string &AccountPath werden (falls du das const vor char vergessen hast, solltes du die Referenz auch const machen)
    
    	void UpdateAccount (HWND hWnd); //immernoch komischer name
    
    	bool Deinitialize (); //würde wahrscheinlich eher ein void Deinitialize nehmen und wenn was schief geht ne exception werfen
    //aber ohne die genauen Aufgaben und möglichen Fehler zu kennen ist das schwer zu beurteilen
    
    private:
            typedef std::map<std::string, ACCOUNT_INFO*> TaccountData; //ein typedef ermöglicht dir dann einfacher an den iterator/... der klasse zu kommen
            TaccountData accountData;
    

    Profile.cpp

    bool CAccountProfile::LoadAccounts(const char *pAccountPath, HWND hWnd)
    {
        ACCOUNT_INFO* AccToAdd = new ACCOUNT_INFO; //besserer var-name!?
    
        /* durch Textdatei durchwühlen und dann zur Map hinzufügen. */
    
        accountData.insert ( std::make_pair (accRemark, AccToAdd) ); //this brauchst du hier nicht
        return true; //warum dann überhaupt nen Rückgabewert? sieht auch wieder stark nach exception aus...
    }
    void CAccountProfile::UpdateAccount(HWND hWnd)
    {
        const LRESULT changed = SendMessage (GetDlgItem(hWnd, cmbAccProfile), CB_GETCURSEL, 0, 0);
    
        char tmp[128] = {0};
        SendMessage(GetDlgItem(hWnd, cmbAccProfile), CB_GETLBTEXT, changed, (LPARAM)tmp);
    
        const std::string chan = tmp; //variablen sollten immer erst dort deklariert werden, wo sie gebraucht werden (und können damit auch meist direkt richtig initialisiert werden
        TaccountData::iterator iter = accountData.begin(); //unserem typedef sei dank sieht das ganze auch schon fast leserlich aus
    
    //und wir machen aus dem while nen for - iter und end habe ich der übersichtlichkeit halber mal getrennt voneinander definiert und nicht im schleifenkopf - vll brauchst du ja auch zumindest eins von beiden noch nach der Schleife 
    //(außerdem sieht das ja stark so aus, als ob accountData.find() genau das ist, was du suchst ^^
        const TaccountData::iterator end = accountData.end();
        for(/*deklarationen+definitionen sind schon alle fertig*/; iter != end; ++iter)
           {
               //was auch immer hier hin sollte
           }
    }
    

    Vll hilft es dir ja ein wenig mehr durchzusehen und damit erst mal die wichtigste Vorraussetzungen zu erfüllen, das ganze mit dem Debugger durchgehen zu können

    Noch was grundsätzliches zum Design:
    Ich glaube nicht, dass ACCOUNT_INFO ein toller klasen (bzw. struct)-Name ist und ich würde auch mal stark anzweifeln, dass er Design-technisch gesehen in die Verwaltungs-Klasse rein sollte...

    bb



  • in der Funktion LoadAccount: wo kommt accRemark her?



  • Sorry Boyz, hat sich erledigt, habe mir Bier gekauft. Klappt auch viel besser jetzt.



  • Wir brauchen nen Ugly- Smilie ⚠



  • @unskilled

    Danke. Man lernt nie aus.

    @bier

    Ha! Wie lustig, nicht ich.

    @Everest

    Wie schon oben erwähnt, wusste ich nicht das man den "Nachrichtentext" größer machen kann, daher sieht es auch so aus. Lesen bevor man irgendwas zum Thema schreibt schadet bekanntlich nie.

    Nun. Habs mit hilfe von unskilled's post geschafft, danke. 🙂


Anmelden zum Antworten