std::list.clear() schlägt fehl



  • Hallo Forum!

    Ich habe ein Problem aufräumen von meinem Speicher.
    Ein poste mal zu erst die Klassen, Vektoren bzw. Listen, die in der DLL bzw. im Header dazu deklariert habe.
    Als Compiler setzte ich Microsoft Visual C++ 2005 ein.

    #ifdef PARSER_EXPORTS
    #define PARSER_API __declspec(dllexport)
    #else
    #define PARSER_API __declspec(dllimport)
    #endif /* #ifdef PARSER_EXPORTS */
    

    Ich habe den folgenden Vektor:

    typedef std::vector<unsigned long> VECTORUNIONS
                                   , *PVECTORUNIONS;
    

    Daneben die folgende Klasse, die mir Probleme bereitet:

    class CSTATIONENTRY
    {
    private:
                 std::string   m_sStationName;
                 unsigned long m_ulLogID;
                 VECTORUNIONS  m_VecUnions;
                 unsigned long m_ulLineNum;
    public:
      PARSER_API               CSTATIONENTRY       ( void );
      PARSER_API              ~CSTATIONENTRY       ( void );
      PARSER_API std::string   GetStationName      ( void ) const ;
      PARSER_API bool          SetStationName      ( const std::string   &sStationName );
      PARSER_API unsigned long GetLogID            ( void ) const ;
      PARSER_API bool          SetLogID            ( const unsigned long  ulLogID );
      PARSER_API bool          GetUnions           (       VECTORUNIONS * pVectorUnions ) const ;
      PARSER_API bool          SetUnions           ( const VECTORUNIONS * 
                                                                              const pVectorUnions
                                                   );
      PARSER_API unsigned long GetLineNum          ( void ) const ;
      PARSER_API bool          SetLineNum          ( const unsigned long  ulLineNum );
    
      PARSER_API bool          ResetAllData        ( void );
    }; /* class CSTATIONENTRY */
    

    Dann folgt noch ein typedef:

    typedef std::list<CSTATIONENTRY> STATIONLIST
                                 , *PSTATIONLIST;
    

    Und noch eine Klasse (leicht gekürzt):

    class CParser
    {
    private:
                               CSTATIONENTRY
                                         m_Station;
                               STATIONLIST
                                         m_listStations;
    public:
      PARSER_API               CNetkondat_Parser   ( void );
      PARSER_API              ~CNetkondat_Parser   ( void );
    
      PARSER_API unsigned long GetStationList      ( const PSTATIONLIST pStationList ) const ;
    }; /* class CParser */
    

    Die Funktion "GetStationList" ist wie folgt implementiert:

    unsigned long CParser::GetStationList( const PSTATIONLIST pStationList ) const
    {
      unsigned long               ulReturn    = 0;
      STATIONLIST::const_iterator StationIter = m_listStations.begin();
    
      pStationList->clear();
    
      for ( StationIter  = m_listStations.begin()
          ; StationIter != m_listStations.end()
          ; ++StationIter
          )
      {
        pStationList->push_back( (*StationIter) );
      } /* for ( StationIter = m_listStations.begin(); ... ) */
    
      return ( ulReturn );
    } /* GetStationList( const PSTATIONLIST pStationList ) */
    

    Die Daten werden über die Folgende Methode in die Liste eingefügt:

    m_listStations.push_back( m_Station );
    

    "m_Station" ist dabei wie oben ersichtlich ein privater Member der Klasse "CParser", die immer wieder aufs neue mit Daten gefuellt wird.

    So, dann ganze ist eine DLL gegossen und klappt auch so weit. Aus meinem Programm komme ich an die Elemente in der List durch den folgenden Aufruf einer Methode einer weiteren Klasse, die nicht in der DLL liegt, zugreifen. Implementierung s.o.

    m_pNetkondatParser->GetStationList( &m_listStationsIn );
    

    Ich kann auch wunderbar auf die Elemente in Liste zugreifen.
    Nur jetzt kommen wir zu meinem Problem, wenn ich die Liste "m_listNetkondatStationsIn" die ein private Memember ist leeren möchte, schmiert mir das Programm mit einem Speicherfehler ab.
    Also der Aufruf "m_listStationsIn.clear()" verabschiedet sich dann. 😕

    Leider weiß ich im Moment nicht weiter und hoffe auf Hilfe von euch.
    Danke schon mal.

    MfG

    naujo



  • Ist die DLL gegen die gleiche Laufzeit gelinkt wie das Program welches die DLL nutzt? (Debug vs. non-Debug, Threaded vs. non-Threaded usw)



  • Hi!

    Also ich habe noch mal alle Einstellungen in der IDE mit einander verglichen.
    Und sie sind gleich, so weit es möglich ist.

    MfG

    naujo



  • Hi

    1.)
    Bei

    pStationList->clear();

    wird bei jedem Eintrag der dtor der CSTATIONENTRY Objekte aufgerufen. Kannst Du soweit noch debuggen, oder gibts vorher schon Ärger?

    2.)
    Ist es richtig, dass alles gut geht, wenn Du zuerst

    m_listStationsIn.clear()
    

    und dann

    m_pNetkondatParser->GetStationList( &m_listStationsIn );
    

    aufrufst, wo bei in GetStationList(..) kein clear auf den vector mehr gemacht wird?

    Gruss simon



  • Hallo simon!

    zu 1)

    Die Eingabelist bereits leer und das klappt noch. Der Aufruf ist nur zur Sicherheit, damit die Liste auch wirklich leer ist.

    zu 2)

    Meine Probleme mit dem clear tauchen erst auf, wenn ich die Funktion

    m_pNetkondatParser->GetStationList( &m_listStationsIn );
    

    Aufgerufen habe und dann eben ein

    m_listStationsIn.clear()
    

    machen möchte. 😞

    Vorher geht es gut, da die Liste leer ist. Und nur durch die oben genannte Funktion gefüllt wird.

    Der Destor wird immer angelaufen und am Ende vom leeren Destor kommt dann der Fehler. 😕

    MfG

    naujo



  • Wird dort Speicher, der in der DLL reserviert wurde, im Kontext der Anwendung freigegeben, bzw. umgekehrt?

    Falls ja ist das das Problem. Beide haben einen eigenen Heap.



  • Hi 7H3 N4C3R!

    Wie oben beschrieben wird in der DLL ein "push_back()" gemacht.
    Aber jetzt wird es mir klar, das es so nicht gehen kann 😞 wenn die Heaps getrennt sind. 😮

    Also es wird im Kontext der DLL der Speicher reserviert. Dann ist es natürlich klar, dass die Freigabe des Speichers im Kontext der Anwendung fehlschlägt.

    Dann werde ich mir mal eine andere Funktion ein fallen lassen müssen, damit es so funktioniert, wie ich mir das vorstelle.

    Ich danke euch für eure Unterstützung und die Lösungsfindung bei meinem Problem!

    MfG

    naujo


Anmelden zum Antworten