Probleme mit shared_ptr und vector.push_back



  • Hallo,
    ich habe ein kleines Problem und ich hoffe ihr könnt mir dabei helfen.
    Ich schreibe gerade als Uebung einen kleinen Handelscomputer fuer X3 Albion Prelude.
    Ich bekomme beim push_back eines shared ptr eine Zugriffsverletzung, allerdings nur in einer Klasse.
    Als ich den Code testweise in die main kopiert habe funktionierte es einwandfrei.
    Ich sehe momentan den Fehler nicht.

    Erstmal das Beispiel das nicht funktioniert.

    //Resource.hpp    Resource Klasse
    #include <string>
    #include <iostream>
    
    class Resource {
    
    public:
        Resource(std::string caption) :
            res_caption(caption) {
            std::cout << "Resource: " << res_caption << std::endl; }
        ~Resource(){}
    
        const std::string res_caption;  
    };
    
    //main cpp
    #include <memory>
    #include <vector>
    #include "Resource.hpp"
    #include <vector>
    
    class Universe {
    
    public:
        Universe(){}
        ~Universe(){}
    
          void find_res(std::string search_item)
        {
         vlist.push_back(std::shared_ptr<Resource>(new Resource("Energiezelle")));
        }
    private:
        std::vector<std::shared_ptr<Resource>> vlist;    
    
    };
    using namespace std;
    
    int main() {
        std::unique_ptr<Universe> uni;
        uni->find_res("Erz");
    
    return 0;
    }
    

    Der Code in der Klasse verursacht einen Ausnahmefehler, es sieht so aus als ob das passiert, wenn der temporaere shared pointer out of scope geht.
    Der Konstruktor von Resource scheint korrekt aufgerufen und abgearbeitet zu werden.
    Wenn ich rein debugge lande ich in der STL bei folgender Funktion:

    bool _Inside(const value_type *_Ptr) const
    {// test if _Ptr points inside vector
        return (_Ptr < this->_Mylast && this->_Myfirst <= _Ptr);
    }
    

    Ich habe den vector und das push_pack dann testweise in die main geschoben und da funktioniert es ohne Probleme.

    siehe:

    using Namespace std;
    int main() {
    
        vector<shared_ptr<Resource>> res_list;
        res_list.push_back(shared_ptr<Resource>(new Resource("Energiezelle")));
        res_list.push_back(shared_ptr<Resource>(new Resource("Agnufleisch")));
    
    return 0;   
    }
    

    IDE ist Visual Studio 2013



  • int main() {
        std::unique_ptr<Universe> uni;
        uni->find_res("Erz");
    
    return 0;
    }
    

    ist falsch. Du erzeugst gar kein Universum sondern nur einen Zeiger darauf.



  • Maxi schrieb:

    int main() {
        std::unique_ptr<Universe> uni;
        uni->find_res("Erz");
       
    return 0;
    }
    

    ist falsch. Du erzeugst gar kein Universum sondern nur einen Zeiger darauf.

    😑
    Vielen Dank.
    Das ist jetzt der richtige Zeitpunkt ins Bett zu gehen und sich auszuschlafen.



  • Eine Frage, die du dir auch noch stellen solltest ist:
    Brauche ich hier wirklich Zeiger oder kann ich nicht auch auto-Objekte (auf dem stack erstellte Objekte) verwenden? In deinem Beispiel sind Zeiger zB überhaupt nicht nötig.



  • Das habe ich mich auch schon gefragt.
    Ich habe hier alles weggestrichen was nicht fuer das Problem gebraucht wird.

    Die Grundidee ist diese:
    X3 AP ist eine Art Weltraumsimulation.
    Ich befinde mich in einem bestimmten Sektor und das Programm soll mir die naechsten Sektoren aufschluesseln in dem ich eine bestimmte Ressource verkaufen kann.
    Also:
    Zeige mir die naechsten Sektoren in denen die Ressource nachgefragt wird.
    Zeige mir primaer den Sektor mit den meisten Abnehmern.
    Zeige mir nur sichere Sektoren.
    Zeige mir den Weg dahin.

    Die Ressourcen und Stationen sind fest, ich lade die Informationen aus einer Datei und befuelle die Vektoren.

    - Ich lade zu erst die Liste der Ressourcen (Anzahl ich glaube ueber 200)
    - Ich lade dann die Liste der Stationstypen (50+)
    - Die Klasse Stationstypen sollen dann 2 Pointer/?SharedPointer? Vectoren haben. Einen fuer Produziert-Ressource und einen fuer Benoetigt Ressource.
    Die Pointer zeigen auf die jeweilige Ressource im Ressourcen Vektor.
    - Dann lade ich die Liste der Sektoren (in einer map) die wiederum Pointer auf die Liste der Stationstypen haben sollen (je nachdem was fuer Stationen in dem Sektor existieren) und Pointer zu den Sektoren zu denen Sprungtore existieren.

    Ich koennte aus den Ressourcen und Stationstypen normale Objekte machen und dann die Verbindungen mit normalen Pointern machen, allerdings dachte ich dann, shared_ptr waere vielleicht huebscher.

    Was meint ihr oder wuerdet ihr eine ganz andere Herangehensweise empfehlen?

    Edit:
    Die Klasse Resource hat noch weitere member.
    - caption
    - description
    - min_preis
    - avg_preis
    - max_preis

    Die Klasse Station hat:
    - caption
    - faction
    - description
    - price
    - benoetigt_res_vektor
    - produziert_res_vector


Anmelden zum Antworten