Dynamische Speicherverwaltung mit Objekten



  • Ein dicker Patzer ist ebenfalls die Zuweisung von char* Literalen an char* member. Da kannst du drauf warten, dass dir deine Anwendung um die Ohren fliegt.
    Wenn du schon keine std::strings verwendest muss du dafür sorgen, dass du den Speicher für deine Zeichenketten selbst verwaltest.



  • Gastbenutzer schrieb:

    ich werd mir new/delete mal angucken.

    Zudem bitte auch std::string und möglichst auch die Containerklassen der Standardbibliothek (std::vector wäre ein guter Einstieg für den Anfang). Oder mindestens - wenn du schon mit C rumhantierst - wie man mit C-Strings umgeht (So wie du es machst ist schlicht und ergreifend falsch).

    Ein möglicher Einstieg:

    #include <string>
    #include <vector>
    
    class Device
    {
      public:
        std::string name;
        std::vector<Device*> devices;
    
        Device();
        virtual ~Device();
        void addDevice(std::string const & name);
        void printAll();
    };
    

  • Mod

    Gastbenutzer schrieb:

    ich werd mir new/delete mal angucken.

    So wie ich dein Programm verstehe, wäre eine Containerklasse besser geeignet. Das wäre auch leichter zu lernen.



  • Hallo nochmal,

    ihr merkt, dass ich mit C++ noch nicht so viel am Hut hatte. 😞

    asc schrieb:

    Gastbenutzer schrieb:

    ich werd mir new/delete mal angucken.

    Zudem bitte auch std::string und möglichst auch die Containerklassen der Standardbibliothek (std::vector wäre ein guter Einstieg für den Anfang). Oder mindestens - wenn du schon mit C rumhantierst - wie man mit C-Strings umgeht (So wie du es machst ist schlicht und ergreifend falsch).

    Ein möglicher Einstieg:

    #include <string>
    #include <vector>
    
    class Device
    {
      public:
        std::string name;
        std::vector<Device*> devices;
    
        Device();
        virtual ~Device();
        void addDevice(std::string const & name);
        void printAll();
    };
    

    SeppJ schrieb:

    Gastbenutzer schrieb:

    ich werd mir new/delete mal angucken.

    So wie ich dein Programm verstehe, wäre eine Containerklasse besser geeignet. Das wäre auch leichter zu lernen.

    Der string gefällt mir sehr gut, aber zu den Containerklassen / Vectoren hätt ich gern noch mehr Infos.

    Zitat von http://www.cpp-entwicklung.de/cpplinux/cpp_main/node6.html#SECTION00633100000000000000:

    Ein besonders wichtiger Container, den wir oben sogar selbst implementiert haben (siehe Seite ), ist der Vektor. Man verwendet ihn normalerweise immer dann, wenn die Anzahl der Elemente zum Zeitpunkt seiner Initialisierung bekannt ist und diese sich auch im Programmverlauf nicht weiter ändert.

    Laut dieser Seite sind die Vectoren ungeignet, da sich die Größe im Programmverlauf ändert. Auch mit dem new Befehl habe ich bisher nur Speicherreservierungen gefunden bei denen die Größe des Arrays von Anfang an bekannt war. Hier soll sich die größe jedoch auch während des Programmlaufs ändern. Daher hätt ich gern nochmal ein Stichwort von euch wie ich diese dynamische Speicherverwaltung wie ich sie brauche implementieren kann.

    Vielen Dank nochmal

    Daniel



  • Das Zitat ist etwas aus dem Zusammenhang gerissen und bezieht sich wohl eher auf C-Arrays. Die Klasse std::vector ist auf keine feste Elementanzahl beschränkt, ganz im Gegenteil. Du kannst zur Laufzeit jederzeit Elemente hinzufügen oder löschen, ohne dich um Speicherverwaltungsdetails kümmern zu müssen.

    PS:
    Für eine Übersicht der C++ Referenz guckst du hier.



  • Gastbenutzer schrieb:

    Laut dieser Seite sind die Vectoren ungeignet, da sich die Größe im Programmverlauf ändert.

    Grundsätzlich ist der std::vector ein dynamischer wachsender Container, wobei jeder Containertyp seine Vor- und Nachteile hat. Der std::vector ist für den Indexzugriff (wie ein Array) ausgelegt, und sehr schnell beim Zugriff. Aber man sollte vermeiden das er zu häufig "wächst" (Die Realisierung erfolgt intern über Arrays, sobald die Elementanzahl nicht mehr ausreicht, wird ein neuer Speicherbereich [in der Regel irgendwo um den Faktor 1,5 und 2 größerer] angefordert. Wenn man die Größe abschätzen kann, sollte man diese mit reserve "vorbelegen").

    Dann gibt es z.B. noch std::list, std::map und einige weitere, die je nach Anwendungsfall besser oder schlechter geeignet sind. std::list ist z.B. beim Wachstum billiger [Verkette Liste], aber im Zugriff "teurer".



  • Okay, dann werd ich mich da mal ranwagen.

    Danke für Eure Hilfe! 😉



  • Das Zitat bezieht sich auf eine selbstdefinierte Klasse namens Vector (man beachte das große V!): http://www.cpp-entwicklung.de/cpplinux/cpp_main/node6.html#Sec:TemplBspVektor



  • Okay.

    Ich habe es denke ich jetzt hinbekommen.

    class Device  
    {
    public:
    	std::string str_Name; 
    	std::vector<Device*> ar_Device; 
    	unsigned int ui_ContainingDevices;
    
    	Device();
    	Device(std::string const & str_Name);
    	virtual ~Device();
    	void addDevice(std::string const & str_Name); 
    	void printAll();
    };
    
    Device::Device(std::string const & str_Name)
    {
    	this->str_Name = str_Name;
    	ui_ContainingDevices = 0;
    }
    
    void Device::addDevice(std::string const & str_Name)
    {
    	ar_Device.push_back(new Device(str_Name));
    	ui_ContainingDevices++;
    }
    
    int main()
    {
    	Device device("Hauptger\204t");
    
    	device.addDevice("Unterger\204t 0");
    	device.addDevice("Unterger\204t 1");
    
    	return 0;
    }
    

    Wenn ich das Programm nach dem hinzufügen des 2. Untergerätes anhalte und debuge finde ich unter

    ar_Device._First..str_Name
    

    den Namen "Untergerät 0". Leider weiß ich nicht wo ich das 2. Untergerät wiederfinde. 😕

    Außerdem weiß ich nicht wie ich meine printAll funktion implementiere.

    void Device::printAll()
    {
    	unsigned int i = 0;
    	cout << "Ger\204t: " << str_Name <<  endl;
    	for(i=0; i<ui_ContainingDevices; i++)
    	{
    		cout << "  Unterger\204t" << i << ": " << ar_Device._First..str_Name << endl;
    	}
    }
    

    Fehlermeldung:

    "_First" : Kein Zugriff auf protected Element, dessen Deklaration in der Klasse "std::vector<class Device *,class std::allocator<class Device *> >" erfolgte

    So müsste es doch richtig sein;

    void Device::printAll()
    {
    	unsigned int i = 0;
    	cout << "Ger\204t: " << str_Name <<  endl;
    	for(i=0; i<ui_ContainingDevices; i++)
    	{
    		cout << "  Unterger\204t" << i << ": " << ar_Device[i].str_Name << endl;
    	}
    }
    

    Fehlermeldung:

    Der linke Teil von '.str_Name' muss eine Klasse/Struktur/Union sein

    Kann mir jemand auf die Sprünge helfen?

    Danke nochmal.


  • Mod

    Wie kommst du auf _First? Wo hast du das überhaupt her? Benutz den Indexoperator [] für den Zugriff, dann wird das schon klappen. Außerdem willst du wohl eher Instanzen von Device in deinem Vektor speichern und nicht Zeiger auf Device.



  • Hallo SeppJ,

    ja das hatte ich mir auch schon gedacht. Allerdings habe ich im Netzt ähnliche Implementationen gefunden.

    Auf das _First komme ich durch den Debugger. Ich habe mir das Objekt angeguckt und dort war dieses Element enthalten.

    Der von DocShoe gepostete Link lässt vermuten, dass sich das i-te Element folgendermaßen ansprechen lässt:

    ar_Device.at(i).str_Name
    

    Fehlermeldung:

    Der linke Teil von '.str_Name' muss eine Klasse/Struktur/Union sein

    Naja, mein Kopf raucht ohne Ende. Ich mach morgen weiter.

    Vielen Dank an Euch alle für die Hilfe!

    Daniel


  • Mod

    Dein Fehler liegt da drin, dass du Zeiger auf Device in deinem Vektor gespeichert hast, du aber versuchst das gespeicherte wie ein Device anzusprechen. Entscheide dich für eines von beiden. Und wenn du dich für die Variante mit den Zeigern entscheiden willst, nennst du bitte ein paar gute Gründe.



  • SeppJ schrieb:

    ...Und wenn du dich für die Variante mit den Zeigern entscheiden willst, nennst du bitte ein paar gute Gründe.

    Ist folgendes inzwischen möglich?

    struct A
    {
        std::vector<A> as;
    }
    

  • Mod

    asc schrieb:

    SeppJ schrieb:

    ...Und wenn du dich für die Variante mit den Zeigern entscheiden willst, nennst du bitte ein paar gute Gründe.

    Ist folgendes inzwischen möglich?

    struct A
    {
        std::vector<A> as;
    }
    

    Ok, das ist ein guter Grund 👍



  • Funktioniert.

    Vielen Dank an Euch! 😉


Anmelden zum Antworten