Memory Leaks



  • Ist dahinter die Funktion schon zu Ende 😕

    Du solltest vermutlich pskNewKey entweder irgendwo speichern (bzw. ans Hauptprogramm zurückgeben) oder vor dem return wieder freigeben (delete).



  • Nein, das war nur ein Teil aus der Funktion.

    Hier kommt die gesamte Funktion:

    void CSyntaxColorizer::addKey(LPCTSTR Keyword, CHARFORMAT cf, int grp) //add in ascending order
    {
    	SKeyword* pskNewKey = new SKeyword;
    	SKeyword* prev,*curr;
    
    	//the string pointed to by Keyword is only temporary, so make a copy 
    	// of it for our list
    	pskNewKey->keyword = new TCHAR[strlen(Keyword)+1];
    	strcpy(pskNewKey->keyword,Keyword);
    
    	pskNewKey->keylen = strlen(Keyword);
    	pskNewKey->cf = cf;
    	pskNewKey->group = grp;
    	pskNewKey->pNext = NULL;
    	*(m_pTableZero + pskNewKey->keyword[0]) = KEYWORD;
    
    	//if list is empty, add first node
    	if(m_pskKeyword == NULL)
    		m_pskKeyword = pskNewKey; 
    	else
    	{
    		//check to see if new node goes before first node
    		if(strcmp(Keyword,m_pskKeyword->keyword) < 0)
    		{
    			pskNewKey->pNext = m_pskKeyword;
    			m_pskKeyword = pskNewKey;
    		}
    		//check to see if new keyword already exists at the first node
    		else if(strcmp(Keyword,m_pskKeyword->keyword) == 0)
    		{
    			//the keyword exists, so replace the existing with the new
    			pskNewKey->pNext = m_pskKeyword->pNext;
    			delete m_pskKeyword->keyword; delete m_pskKeyword;
    			m_pskKeyword = pskNewKey;
    		}
    		else
    		{
    			prev = m_pskKeyword;
    			curr = m_pskKeyword->pNext;
    			while(curr != NULL && strcmp(curr->keyword,Keyword) < 0)
    			{
    				prev = curr;
    				curr = curr->pNext;
    			}
    			if(curr != NULL && strcmp(curr->keyword,Keyword) == 0)
    			{
    				//the keyword exists, so replace the existing with the new
    				prev->pNext = pskNewKey;
    				pskNewKey->pNext = curr->pNext;
    				delete curr->keyword; delete curr;
    			}
    			else
    			{
    				pskNewKey->pNext = curr;
    				prev->pNext = pskNewKey;
    			}
    		}
    	}
    }
    


  • Bau mal in deinen Destruktor eine Schleife ein, die die komplette Keyword-Liste aufräumt, wenn das Objekt gelöscht wird.



  • Das habe ich schon probiert.
    Ich habe im Destruktor Clear Keywordlist aufgerufen.
    Der Quellcode:

    void CSyntaxColorizer::ClearKeywordList()
    {
    	SKeyword* pTemp = m_pskKeyword;
    
    	while(m_pskKeyword != NULL)
    	{
    		*(m_pTableZero + m_pskKeyword->keyword[0]) = SKIP;
    		if(_stricmp(m_pskKeyword->keyword,"rem") == 0)
    			*(m_pTableTwo + '\n') = SKIP;
    		pTemp = m_pskKeyword->pNext;
    		delete m_pskKeyword->keyword;
    		delete m_pskKeyword;
    		m_pskKeyword = pTemp;
    	}
    }
    

    Bei der Programmausführung wird der Debugger mit einer Fehlermeldung:
    "Unbehandelte Ausnahme" unerbrochen und springt die MFC interne Datei free.c auf die Zeile: HeapFree(_crtheap, 0, pBlock); 😞



  • array new und scalares delete gehen nicht gut zusammen, auch wenn das hier sicher nicht das problem ist. Im übrigen könnte man beides sparen, wenn CString benutzt würde.

    Paule 0 schrieb:

    Bei der Programmausführung wird der Debugger mit einer Fehlermeldung:
    "Unbehandelte Ausnahme" unerbrochen und springt die MFC interne Datei free.c auf die Zeile: HeapFree(_crtheap, 0, pBlock); 😞

    benutz den callstack um den aufrufer (und die parameter beim aufruf) festzustellen.



  • Achja, nochwas: Hat es einen Grund, daß du die verkettete Liste selber implementierst? Ich würde dir dafür eher std::list oder std::set (oder die MFC-Versionen davon) empfehlen.



  • Die Keywordlist enthält meine selbsterstellten Schlüsselwörter.
    Ich weiß nicht wie ich das anders lösen könnte. 😕



  • ich würde std::map empfehlen



  • class SKeyWord
    {
      //...
      char* keyword;
      bool operator<(const SKeyWord& other)
      {return strcmp(keyword,other.keyword)<0;}
      //oder besser gleich:
    
      std::string keyword;
      bool operator<(const SKeyWord& other)
      {return keyword<other.keyword;}
    };
    
    class CSyntaxColorizer
    {
      std::set<SKeyWord> m_KeyWords;
      //...
    };
    
    //Im Quelltext:
    m_KeyWords.insert(newKWD);//einfügen
    m_KeyWords.erase(newKWD); //löschen
    //...
    


  • Entschuldige, dass ich mich jetzt twas blöd anstelle, aber wo soll ich das genau reinschreiben.
    Muß ich eine neue Klasse SKeyWord erstellen?
    Danke!



  • #include <map>

    und anstelle deiner eigenen Liste benutz du die std::map



  • Nein, du mußt deine vorhandene SKeyWord-Klasse entsprechend anpassen (für sets/maps benötigst du einen Vergleichsoperator - und eine vordefinierte String-Klasse ist einfacher zu handhaben als char*).



  • beschäftige dich algemein mit associativen standard-containern - dann wird vieles klarer - und deine addKey() methode u.ä. kannst du dann auf 0 zeilen eindampfen 😉

    anonsten kannst du nat. auch versuchen den fehler zu finden, ich kann ihn nicht entdecken (abgesehen vom delete[] auf ->keyword und das führt bei vc++ häufig nicht zu abstürzen), allerdings schaue ich es mir auch nicht besonders intensiv an


Anmelden zum Antworten