terminate called after throwing ... char* übergabe



  • Hallo,

    ich wollte folgendes machen (Ich weiß dass es nicht C++ strings und stream sind aber bitte es geht mir nur um die pointer-problematik):

    //irgendwo in main
    
    char * file_path = NULL;
    
    Foo f = Foo(file_path);
    
    std::cout<< std::string(file_path) << std::endl;
    
    //Header von Foo
    
    class Foo
    {
         public:
             Foo(char*& f_path);
    
             bar();
         private:
           char *m_file_path;
    };
    

    [cpp]
    // in Implementierung von Foo

    Foo::Foo(char*& f_path)
    {
    m_file_path = *&f_path;
    }

    Foo::bar()
    {
    static char tx_path[256];

    //weise pfad aus konsole zu
    strcpy(tx_path,argv[1]);
    m_file_path = shell_path;
    }
    [cpp]

    Es kracht mit der Meldung:

    terminate called after throwing an instance of std::logic_error
    what(): basic_string::_S_construct NULL not valid
    Aborted
    

    in der main ist das char* nicht gesetzt. Nur wie kann ich das rihctig setzen?



  • also ich will in worten folgendes erreichen:

    ich will den char* den ich übergebe über einen private-member der klasse ändern. dazu lasse ich einen private-pointer der klasse auf die adresse von dem übergebenen char zeigen und will damit den dereferenzierten pointer ändern. Damit sollte doch die variable da sie änderbar ist sich nach außen hin auch ändern oder nicht?



  • also um den fehler wegzubekommen reichts wenn du ind er deklaration udn ind er definition das & zeichen wegmachst...



  • hmm...ich will doch aber den member verändern...mit deinem vorschlag bleibt der fehler



  • eh nicht den member...ich will doch die übergebene variable ändern...



  • Mach Foo::m_file_path auch vom Typ " char*& ", die Variable musst du dann in der Initialisierungsliste des Konstruktors mit dem Parameter belegen und die Klasse wird unkopierbar. Alternativ könnte Foo::m_file_path auch ein " char** " sein und du belegst den Zeiger im Konstruktor oder Initialisierungsliste mit " m_file_path = &f_path (die Klasse ist damit auch kopierbar).



  • hmm...das funktioniert auch nicht...so bekomme ich einen segmentation fault

    hier nochmal der code

    //irgendwo in main
    
    char * file_path = NULL;
    
    Foo f = Foo(file_path);
    
    std::cout<< std::string(file_path) << std::endl;
    
    //Header von Foo
    
    class Foo
    {
         public:
             Foo(char*& f_path);
    
             bar();
         private:
           char **m_file_path;
    };
    
    // in Implementierung von Foo
    
    Foo::Foo(char*& f_path)
    {
       m_file_path = &f_path;
    }
    
    Foo::bar()
    {
    static char tx_path[256];
    
    //weise pfad aus konsole zu
    strcpy(tx_path,argv[1]);
    *m_file_path = shell_path;
    }
    


  • gambo schrieb:

    hmm...das funktioniert auch nicht...so bekomme ich einen segmentation fault

    Genau deshalb wird hier ja auch immer zu std::string geraten 😉 Debugge doch mal und schau, wo genau der Fehler auftritt. Übrigens, file_path ist bei std::string(file_path) noch NULL.



  • Ich hab ein bisschen rumprobiert und man kann wirklich einen Pointer auf ein privates Member einer Klasse zeigen lassen. Aber das ist nun wirklich nicht der Sinn von 'privaten' Membervariablen! Ich wusste leide nicht, was du mit der Variablen shell_path machst, ich hab das etwas angepasst und hoffe vereinfacht.

    Man übergibt nicht nicht einen Pointer, sondern vielmehr die Adresse des Pointers, so auf die Speicherstelle schreiben, wo file_path hinzeigt und ihn auf die Membervariable m_file_path zeigenlassen.

    #include <iostream>
    #include <cstring>
    
    class Foo
    {
    public:
      Foo( char **f_path );
      void bar( char **argv );
    private:
      char *m_file_path;
    };
    
    Foo::Foo( char **f_path )
    {
      *f_path = (char*)&m_file_path;
    }
    
    void Foo::bar( char **argv )
    {
      static char tx_path[256];
      strcpy( tx_path, argv[1] );
      m_file_path = tx_path;
    }
    
    int main( int argc, char **argv )
    {
      char **file_path = NULL;
      Foo f = Foo((char**)&file_path);
    
      f.bar( argv );
    
      std::cout << std::string(*file_path) << std::endl;
    
      return 0;
    }
    


  • Ich hab ein bisschen rumprobiert und man kann wirklich einen Pointer auf ein privates Member einer Klasse zeigen lassen.

    danke für deine hilfe aber ich wollte gerade das umgekehrte realisieren. Ich will einen privaten member auf einen übergebenen pointer (den char * - string sozusagen) zeigen lassen damit ich nicht ständig das char-array in jede funktion durchschleifen muss um es zu belegen. Ich dachte ich lasse einen member der klasse draufzeigen und belege dann immer nur den member und am schluss ist sollte die die speicherzelle auf die der pointer zeigt so belegt sein dass ich meinen string auch außerhalb der klasse auslesen kann....



  • ...ich habe jetzt etwas nachgedacht und überlege sowas. Wäre es vielleicht sauberer/korrekter die member öffentlich zugänglich zu machen und einfach nur die member zu belegen?

    Also so?

    //irgendwo in main
    
    Foo f = Foo();
    
    std::cout<< std::string(f.file_path) << std::endl;
    
    //Header von Foo
    
    class Foo
    {
         public:
             Foo();
    
             bar();
    
            char *m_file_path;
    };
    
    // in Implementierung von Foo
    
    Foo::Foo()
    {
       m_file_path =  NULL;
    }
    
    Foo::bar()
    {
    static char tx_path[256];
    
    //weise pfad aus konsole zu
    strcpy(tx_path,argv[1]);
    m_file_path = shell_path;
    }
    

Anmelden zum Antworten