strcpy und struct



  • Hi,
    Kannst du mir sagen ob ich das so richtig mache?(Habe es mit den Adressen nicht so):

    struct data {
      int id;
      char* buffer;
    };
    void thread(void* arg)
    {
    int i = static_cast<data*>(arg)->id;
    int size = strlen(static_cast<data*>(arg)->buffer);
    char* buf = new char[size+1];
    strcpy(buf,static_cast<data*>(arg)->buffer);
    //blablabla
    delete [] buf;
    //lösche struct:
    delete [] &arg; // Ist das so richtig? 
    }
    int main(void)
    {
    //blabla
    data* ver = new data;
    ver.id = i;
    // starte ptherad und übergebe adresse
    }
    

    MFG ReduX



  • Aufräumen;

    struct thread_data_t
    {
        unsigned int id;
        char* data;
    
        thread_data_t(const char* string = NULL, const unsigned int id = 0)
            : data(new char[std::strlen(string)]()), id(id)
        {
            std::strcpy(data, string);
        }
        ~thread_data_t()
        {
            delete [] data;
        }
    };
    
    void thread(void* ptr_arg)
    {
        thread_data_t* ptr_data(static_cast<thread_data_t*>(ptr_arg));
    
        // copy data
        const unsigned int id(ptr_data->id);
        char* data(new char[std::strlen(ptr_data->data) + 1]());
        std::strcpy(data, ptr_data->data);
    
        // TODO: Do something!
    
        delete [] data;
    }
    
    int main()
    {
        thread_data_t* ptr_data(new thread_data_t("Test", 10));
        thread(ptr_data);
        delete ptr_data;
    }
    

    was du da machen wolltest geht nicht, da du nicht einen void-Zeiger löschen kannst, weil dieser keine Größe hat!



  • ReduX schrieb:

    ...optimalsten...

    Oh Oh Oh ... wenn ich da nicht mal wieder 4 Seiten Germanistik-Diskussion heranrauschen höre !!! 😉

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Oh Oh Oh ... wenn ich da nicht mal wieder 4 Seiten Germanistik-Diskussion heranrauschen höre !!! 😉

    Gruß,

    Simon2.

    Och, der Link zu den anderen 8 Seiten von neulich würd doch schon reichen ^^



  • Hi,
    Danke für deine Antwort!
    Der Code läuft soweit nur stürtzt das Programm ab.
    Ich denke es liegt daran:

    int main()
    {
        thread_data_t* ptr_data(new thread_data_t("Test", 10));
        thread(ptr_data);
        delete ptr_data; // Im thread wurden die Daten wahrscheinlich nochnicht rauskopiert!
    }
    

    Kann ich statt im main die daten auch im thread löschen?

    MFG ReduX



  • ja ... aber am saunbersten wäre es, wenn du auf den Thread warten würdest ...



  • Tag,
    Also das Problem ist dabei das der main thread an einen Port gebunden ist und auf clients horcht. Ich übergebe dann wenn einer Connected die id an den thread um weiter zu verfahren. Da kann ich nicht warten weil sonst würde der ganze Server blockieren. Bzw. was ist daran nicht sauber? gibts dadurch speicherleaks oder so?

    MFG ReduX



  • ReduX schrieb:

    Bzw. was ist daran nicht sauber? gibts dadurch speicherleaks oder so?

    Normalerweise sollte derjenige Teil, der den Speicher anfordert, ihn auch wieder freigeben. In diesem Fall ist es meiner Meinung nach aber ok, wenn der Haupthread den Speicher anfordert und der gestartete Thread ihn wieder freigibt. Dürfte auch keine Speicherlecks geben, also von daher alles ok.

    Wenn du nur einen Wert übergeben willst und sizeof(Wert)<=sizeof(void*) gilt, dann kannst du deinen Wert auch zu einer Adresse casten, der Thread castet den void-Zeiger wieder auf den Wert um und du brauchst keinen Speicher zu allokieren/freizugeben.



  • Hi,
    Danke für deine Antwort.
    Das Problem ist ich weiß nicht wie ich es im Thread mit delete löschen soll.
    Habe mit Adressen irgendwie Probleme weil in void*arg steht ja die Adresse drin aber warum geht dann "delete arg" nicht?

    MFG ReduX



  • Weil es ein void-Pointer ist. Und was soll er denn dann dort löschen wo der Zeiger hinzeigt? Void/nichts?



  • Hi,
    Irgendwie stürtzt das Programm immer noch ab. Hier der Vorab Code(Patchwork):

    struct data
    {
        unsigned int id;
        char* info;
    
        data(const char* string = NULL,const unsigned int id = 0) : info(new char[strlen(string)]),id(id)
        {
            strcpy(info, string);
        }
        ~data()
        {
            delete [] info;
        }
    };
    void verification(void* arg)
    {
    data* ptr_data(static_cast<data*>(arg));
    unsigned int i(ptr_data->id);
    int size = strlen(ptr_data->info);
    char* buffer = new char[size+1];
    strcpy(buffer,ptr_data->info);
    printf("ID: %id, Buffer: %s",i,buffer);
    delete [] buffer;
    }
    int main()
    {
    while(1) {
    if(event) {
    data* ver(new data("TestTest",32));
    _beginthread(verification,0,&ver);
    }
    }
    }
    

    MFG ReduX



  • new char[strlen(string)]
    =>
    new char[strlen(string)+1]

    Oder einfach std::string verwenden...

    und darf man fragen, wieso du Variablen so data* ver(new data("TestTest",32)); initialisierst, anstatt data* ver = ... ?



  • #include <cstring> // std::strcpy, std::strlen
    #include <iostream> // std::cout, std::endl
    
    struct data
    {
        unsigned int id;
        char* info;
    
        data(const char* string = NULL, const unsigned int id = 0) 
            : info(new char[std::strlen(string) + 1]()), id(id) // hier + 1 bei info-initialisierung, da sonst Nullterminierung fehlt!
        { std::strcpy(info, string); }
    
        ~data()
        { delete [] info; }
    };
    
    void verification(void* arg)
    {
        data* ptr_data(static_cast<data*>(arg));
    
        // const, du veränderst nichts mehr an der id!
        const unsigned int id(ptr_data->id);
        // const, denn auch die Größe veränderst du nicht ;)
        const std::size_t size(std::strlen(ptr_data->info) + 1);
        char* buffer(new char[size]);
        std::strcpy(buffer, ptr_data->info);
    
        std::cout << "ID: " << id << ", Buffer: " << buffer << std::endl;
    
        delete [] buffer;
    }
    
    int main()
    {
        while(1) 
        {
            if (event) 
            {
                data* ver(new data("TestTest", 32));
                ::_beginthread(verification, 0, ver); // WARUM &ver? ver ist schon ein Zeiger!
            }
        }
    }
    

    Aber einfacher:

    #include <string>
    
    void verification(void* arg)
    {
        data* ptr_data(static_cast<data*>(arg));
        std::cout << "ID: " << ptr_data->id << ", Buffer: " << ptr_data->info << std::endl;
    }
    

    ... 😉



  • Oder eben mit strings (!!)

    #include <cstring> // std::strcpy, std::strlen
    #include <iostream> // std::cout, std::endl
    #include <string> // std::string
    
    struct data
    {
        unsigned int id;
        std::string info;
    
        data( const std::string str="", const unsigned int id=0 ) : info(str), id(id)
        { }
    };
    
    void verification( void* arg )
    {
        data* my_data = reinterpret_cast<data*>( arg );
        std::cout << "ID: " << my_data->id << ", Buffer: " << my_data->buffer << std::endl;
        delete my_data;
    }
    
    int main()
    {
        while(1)
        {
            if (event)
            {
                ::_beginthread( verification, 0, new data("TestTest",32) );
            }
        }
    }
    


  • @Badestrand: Kennst aber schon Referenzen? 😉



  • Hi,
    Danke für eure Antworten.
    Also abstürtzen tut es jetzt nicht mehr 🙂
    Jetzt hab ich nurnoch eine fragen:
    Muss ich wenn ich mit recv empfange das char array null terminieren? Also:

    buf[1024];
    rc = recv();
    buf[rc] = '\0';
    

    ist das notwendig?

    MFG ReduX


Anmelden zum Antworten