Linked Liste, Speicherverwaltungsfehler



  • otze schrieb:

    ne die std::list hat keine namen/wert abhängigkeiten, wie sie hier verlangt werden.

    Du kannst aber eine Liste von Paaren nutzen, beides ist in der STL.



  • Hallo Leute,

    erstmal danke für die zahlreichen antworten.

    Bei einigen Antworten muss ich mir jedoch erst das entsprechende Wissen nochmals reinziehen.
    Man merkt wohl, das ich führ mehr C Programm geschrieben habe und ausser die üblichen C++ Lernprogramme, dies mein erstes wirkliches C++ Programm wird.

    Ich nehme daher die Kritik gerne an. Insbesondere das mit dem New und delete stimmt.

    Hier noch das Interface und die Struktur von der Liste

    typedef struct tag_IOElement IOElement;
    
    struct  	tag_IOElement {
             unsigned char	I2CAdresse;				// I2C Adresse 0=Memory Var
    			unsigned char	Enabled;    			// Ist diese Variable aktiv
             unsigned char	Locked;              // Ist eine Sperre auf diese Var.
             char	Name[10];							// Name der Variable
             long	InitValue;							// Startwert der Variable
             unsigned char	ScanRate;            // Abtastrate in 100 milli Sek.
             long	Value;                        // Aktueller Wert
             float	LastScan;                     // mSek. seit dem letzten Scan
             unsigned char	Type;                // Datentyp 0=Byte 1=Word 2=Long
             unsigned char	UpdateRequest;       // Wert neu einlesen
             unsigned char	IOAddress;           // I/O Adresse des I2C Slave
             unsigned char	ValueChanged;        // Mitteilung, das Wert geändert hat
             long	NextWriteValue;               // Schreibwert beim naechsten Zyk.
    		  	IOElement	*LastElement;				// Vorheriges Element in der Liste
             IOElement   *NextElement;				// Zeiger auf das naechste Element
    };
    
    // ----------------------------------------------------------------------------
    // 					Interface des IO Buffer Objektes
    // ----------------------------------------------------------------------------
    
    class PitbullyIOBuffer
    {
    private:													// Siehe jede Instanz nur
         	IOElement	*ActualElement;				// Actives Element der Instanz
    
    protected:                                	// Sehen alle Instanzen gleich
    
       	int			AnzahlDerInstanzen;			// Anzahl der Objekte
         	IOElement	*MainListe;						// HauptListe
    
    public:
    
       	PitbullyIOBuffer(void);                // Konstruktor
          ~PitbullyIOBuffer(void);               // Destruktor
    
          void	SetVariableName(char*);				// Setze den Namen der Var.
          char*	GetVariableName(void);				// Ermittle den Variblen Name
    
          // Setze/frage nach Eigenschaften der Verbindung
    
          void	SetEnableStatus(unsigned char);	// Freigabe der Var. steuern
          int	SetLockStatus(unsigned char);		// Sperrung der Var. setzen
    
          int	IsEabled(void);						// Ist die Variable freigegeben
          int   IsLocked(void);                  // Ist die Variable gesperrt
          int	IsNew(void);							// Hat sich der Wert geaendert
    
          void	MoveFirst(void);      				// Browse Funktionen
          void	MoveNext(void);
          void	MoveLast(void);
          int	EndOfFile( void );
          int	BottomOfFile( void );
    
          //  Informationsfelder fuer die Erstellung einer Verbindung
    
          void	SetScanRate(unsigned char);		// Scanrate festlegen
    		void	SetIOSize( unsigned char );		// Groesse der Variable
          void  SetI2CAdress(unsigned char);		// Setze die aktive I2C Adresse
          void	SetIOAdress(unsigned char);      // Zieladresse des Slave
          void	SetInitValue(long);					// Basis Wert, bis eingelesen
    
       	void	AddItem(char*);                   // Fuege eine neues Element hinzu
          void	RemoveItem(void);                // Entfernt einen Block
    
    		// Memberroutinen, welche Übertragungsfunktionen ausführen
    
          void	DoEvent(void);							// Ausstehende Events durchführen.
          long	GetValue(void);						// Wert ermitteln
          long	SetValue(void);                   // Wert setzen
    };
    

    Reserviert man unter C++ noch Speicher in der Art String[10] ? 😕

    Ach ja, der Quellcode sieht bei mir auf dem Bildschirm etwas besser eingerückt aus.

    Gruss



  • Ach ja,

    nur zur Info. Der Compiler ist schon etwas älter, da ich unbeding 80186 Code benötigt.

    So, ich habe den Fehler gefunden. In der InitRoutine des Klasse habe ich vergessen im Ursprungszeiger das Link-Element zu setzen.

    Danach noch bei dem ersten Additem das Root Element vermerken. (zeiger anpassen).

    Gruss



  • otze schrieb:

    ne die std::list hat keine namen/wert abhängigkeiten, wie sie hier verlangt werden.

    Hö? Ich seh nur, daß er beim Einfügen schaut, ob bereits ein Element dieses Namens existiert. Das kann er doch genauso mit std::list und find() aus <algorithm> machen...



  • Hi Cocaine,

    wie geht das den mit std::list und find() ?

    Diese Funktion kenne ich noch nicht.

    Gruss



  • @cocaine schau dir mal an wie das datenobjekt ausschaut welches er benutzt, und dann sag mir, ob ein find funktionieren würd 🙄.

    wenn dann std::find_if.

    std::find_if durchsucht die liste mithilfe einer funktion die man bestimmen kann.
    mehr dazu gibts hier:
    http://www.sgi.com/tech/stl/find_if.html

    und am besten immernoch die gute alte map, dann braucht man nämlich keinen algorithmus zu benutzen und hat weniger schreibarbeit.(und in der geschwindigkeit nimmt sich das auch nicht viel)



  • otze schrieb:

    @cocaine schau dir mal an wie das datenobjekt ausschaut welches er benutzt, und dann sag mir, ob ein find funktionieren würd 🙄.

    wenn dann std::find_if.

    Hast recht. Dachte an nen operator==, aber mit dem geht's ja nur, wenn man die Elemente nicht als Pointer in die Liste legt.

    Ich schreib hier trotzdem mal ein Beispiel, damit Ritchie sieht, wie man std::find benutzen kann (ich geb auch gerne zu, daß ich erst ausprobiert hab, bevor ich dir Recht geben konnte 😉 ):

    #include <iostream>
    #include <list>
    #include <string>
    #include <algorithm>
    #include <cassert>
    
    struct MyElement
    {
    	MyElement(const char *new_name)
    		: name_(new_name)		{ }
    	MyElement(const MyElement &other)
    		: name_(other.name_)	{ }
    
    	bool operator==(const char *other)
    	{
    		return name_ == other;
    	}
    
    	std::string	name_;
    };
    
    int main()
    {
    	std::list<MyElement> lst;
    
    	lst.push_back(MyElement("Das"));
    	lst.push_back(MyElement("geht"));
    	lst.push_back(MyElement("doch"));
    	lst.push_back(MyElement("oder?"));
    
    	std::list<MyElement>::iterator it = std::find(lst.begin(), lst.end(), "geht");
    	std::cout << it->name_ << std::endl;
    
    	it = std::find(lst.begin(), lst.end(), "nioht?");
    	assert(it == lst.end());
    
    	return 0;
    }
    

    otze schrieb:

    und am besten immernoch die gute alte map, dann braucht man nämlich keinen algorithmus zu benutzen und hat weniger schreibarbeit.(und in der geschwindigkeit nimmt sich das auch nicht viel)

    Dazu müßte man aber den Namen aus dem Objekt ziehen (also als Index der Map benutzen), oder?



  • ja, würde aber keinen unterschied mehr machen 🙂



  • Hallo Leute,

    ich für zwei Tage Offline und konnte daher nicht antworten. Ist sonst nicht meiner Art. Ich werde mir gleich mal diese Funktion ansehen.

    Scheint ja auf den ersten Blick übersichtlicher zu sein.

    Muss ich aber erst mal verdauen. 😉

    Gruss



  • Tja,

    in meinem C++ gibt es keine cassert. 😮

    Was nun ?

    Gruss



  • Das von mir da oben ist nur ein Anwendungsbeispiel für std::find - nicht so nachbauen, sonst wird, sobald in der std::list ein Copy-Ctor aufgerufen wird, jedesmal der String umkopiert (und das passiert nicht selten).



  • Hi Cocaine,

    der Compiler hat mit der Zeile

    #include <cassert>

    ein Problem.

    Ist es kein lauffähiges Beispiel?

    Ich schreib hier trotzdem mal ein Beispiel, damit ... sieht, ...

    Gruss





  • Hab dich doch nicht paepstlicher als der Papst. Anscheinend ist es ein veralteter Compiler, der cassert nicht kennt. In dem Fall einfach wie gehabt assert.h verwenden.



  • Hallo bashar,

    danke für den Tip.

    Ich kenne leider nicht die ganze Ersetzungen und wusste nicht, das man hier assert.h verwenden muss.

    Gruss



  • Mein Beitrag war eigentlich an Lars gerichtet, aber der hat sich inzwischen wegeditiert.



  • Ne, soweit bin ich noch nicht gegangen... Musste mal Marcus fragen, ob ich kurz Admin werden darf... Dann vielleicht.


Anmelden zum Antworten