memcpy, memmove, calloc, memset in C++?


  • Administrator

    Grüsse zusammen,

    Der eine Thread in diesem Forum artet mal wieder in einem Flamewar aus, ob man C in C++ brauchen darf oder nicht. Da ich aber an diesem Flamewar nicht interessiert bin, sondern an einer ernst gemeinter Frage, habe ich mir nun erlaubt, einen neuen Thread aufzumachen.

    Ich programmiere nicht viel mit "reinem" C++ oder C. Ich benutze oft die MFC oder manchmal die WinAPI. Trotzdem kam es schon mal vor, dass es anderst war 😉

    Man sagt aber eben meistens, dass man in C++ kein C verwenden sollte. Aber wie mache ich in C++ z.b. ein memset? Oder ein calloc? Oder ein realloc? Das sind doch, soweit ich informiert bin, C-Funktionen.

    Bitte kein Flamewar hier drin, möchte nur meine Fragen beantwortet haben.

    Grüssli



  • Hi,

    wie im vorherigen Thread erklärt wurde, ist es bis zu einem bestimmten Umfang okay, Funktionen aus der C Std. Bibliothek herzunehmen, alleine schon deswegen, weil es in C++ oft keine äquivalente Funktionen zu C gibt.

    memset - Hier gibt es keine Äquivalente, also nimmst du diese.
    calloc - In C++ gibt es hierfür den Operator new
    realloc - Dies kann man auch mit Std. C++ lösen, wobei diese Funktion sicherlich die einfachere Variante ist.

    Damit möchte ich letztendlich sagen, dass es in der Tat manchmal nötig ist, C Funktionen zu nehmen. Aber es ist nicht gut, wenn man printf () oder scanf () anstelle von cout und cin nimmt.

    MfG mikey.


  • Administrator

    Mir ging es auch nicht unbedingt darum, ob man es nun darf oder nicht. Ich selber finde es auch unschön, wenn man z.b. fopen, fclose usw. in einem C++ Programm verwendet. Aber wie gesagt, darum geht es mir eigentlich nicht.

    mikey schrieb:

    calloc - In C++ gibt es hierfür den Operator new

    Ist nicht malloc das äquivalent zu new? calloc allokiert nämlich Speicher und setzt ihn auf 0. Macht dies new automatisch? Dann hätte ich z.b. jetzt was neues gelernt 😉

    mikey schrieb:

    realloc - Dies kann man auch mit Std. C++ lösen, wobei diese Funktion sicherlich die einfachere Variante ist.

    Und wie? Das würde mich nämlich genau interessieren, wie man das machen könnte 😉

    Gibt es eigentlich irgendwo eine Seite, welche die Differenzen ganz klar aufzeigt und die alternativen in C++ für die Funktionen in C aufzeigt? Wäre nämlich manchmal echt noch hilfreich 😉

    Grüssli



  • Dravere schrieb:

    mikey schrieb:

    realloc - Dies kann man auch mit Std. C++ lösen, wobei diese Funktion sicherlich die einfachere Variante ist.

    Und wie? Das würde mich nämlich genau interessieren, wie man das machen könnte 😉
    Grüssli

    öh...elemente in ein temporäres array kopieren, delete[] und erneut new aufrufen und dann wieder in das eigentliche array kopieren? 🤡



  • Macht dies new automatisch? Dann hätte ich z.b. jetzt was neues gelernt

    Sorry, malloc ist äquivalent zu new. New setzt den Speicher nicht auf 0.

    Und wie? Das würde mich nämlich genau interessieren, wie man das machen könnte

    Ganz einfach. Du löscht einfach den alten, reservierten Speicherplatz, allokierst dann soviel Speicher, wie angegeben, und gibst dann die Anfangsadresse des reservierten Speicherbereiches zurück. Löschen tut man mit delete bzw. delete []. Aber das steht in jedem C++ Tutorial. Achja, die vorherigen Daten musst du natürlich noch in einem temp. Array abspeichern, siehe oben.

    Gibt es eigentlich irgendwo eine Seite, welche die Differenzen ganz klar aufzeigt und die alternativen in C++ für die Funktionen in C aufzeigt? Wäre nämlich manchmal echt noch hilfreich

    Ja, cppreference.com bietet dir eine gute Übersicht. Allerdings gibt es auch dort keinen direkten Vergleich zu äquivalenten C++ Funktionen.

    MfG mikey.



  • Dravere schrieb:

    mikey schrieb:

    calloc - In C++ gibt es hierfür den Operator new

    Ist nicht malloc das äquivalent zu new? calloc allokiert nämlich Speicher und setzt ihn auf 0. Macht dies new automatisch? Dann hätte ich z.b. jetzt was neues gelernt 😉

    Grüssli

    new - kann man dazu bringen mit Nullen zu initialisieren!

    int* ptr = new int [100](); // 100 int mit 0 initialisiert!
    

    🕶



  • realloc pendant in C++: std::vector

    Bjarne Stroustrup schrieb:

    If you feel the need for realloc() - and many do - then consider using a standard library vector

    http://www.research.att.com/~bs/bs_faq2.html#realloc

    Bjarne Stroustrup schrieb:

    In C++, a better way of dealing with reallocation is to use a standard library container, such as vector, and let it grow naturally.

    http://www.research.att.com/~bs/bs_faq2.html#renew

    Bitte mehr in C++ denken! Die C++-Standardlib hat eigentlich immer eigene Lösungen! Und diese müssen nicht zwangsweise heißen, wie in C.



  • Ne, das klappt nicht. Beim Auslesen der ints sind diese trotzdem mit willkürlichen Werten belegt.

    Mfg mikey.



  • @Dravere
    Dein Ansatz ist bereits falsch. Du versuchst C in C++ zu programmieren. Das ist falsch. Vergiss C und programmier C++. In C++ benutzt man zB eher std::vector oder std::tr1::array, anstelle sich um die Speicherverwaltung zu kümmern. Wenn man dir nun sagt, das man mit new calloc ersetzen kannst, wirst du vermutlich weiterhin C in C++ programmieren, nur eben mit new anstelle calloc...



  • mikey schrieb:

    Ne, das klappt nicht. Beim Auslesen der ints sind diese trotzdem mit willkürlichen Werten belegt.

    vector<int> v1( 100, 0 );
    


  • Artchi, danke dir 🙂

    [EDIT] Dann müssten ja alle Fragen von Dravere beantowrtet sein ... Anstatt malloc nimmt man einen vector, anstatt calloc new und delete bzw. delete [] ...

    MfG mikey.



  • Naja, für malloc() kann man neuerdings auch std::tr1::array nehmen (wie rüdiger schon gesagt hat). Hat aber noch nicht jeder, alternativ boost::array nehmen.

    calloc kann man auch durch einen array oder vector ersetzen. Z.B. einen zweidimensionalen variablen Memmory:

    vector<vector<int>> a;
    
    // nachdem man ihn mit push_back()s gefüllt hat, kann man drauf zugreifen:
    int i = a[0][0];
    //oder
    int i = a.at(0).at(0);
    

    Autom. variabel in beide dimensionen, ohne das man sich drum kümmern muß.



  • Dravere schrieb:

    Aber wie mache ich in C++ z.b. ein memset?

    char a[100];
    std::fill (a, a+100, '1'); // memset (a, '1', 100);
    

    🙂



  • Um noch der Vollständigkeit wegen, die C++ Features zu zeigen:

    using std::tr1::array; // alternativ boost::array
    
    // 10er int-Array
    array<int,10> a = { { 1, 2, 3, 4, 5 } };
    
    // 4er String-Array
    array<std::string,4> seasons = {
            { "spring", "summer", "autumn", "winter" }
    };
    
    // 2D-Array mit Strings:
    array<array<std::string,4>,2> seasons_i18n = {
            { { { "spring", "summer", "autumn", "winter", } },
              { { "Fruehling", "Sommer", "Herbst", "Winter" } }
            }
    };
    
    // -------------------------------------
    typedef array<int, 4> my_array;
    
    my_array a1 = {{ 23 }};
    
    my_array a2(a1); // kopiert a1 in a2
    
    my_array a3;
    a3 = a1;   // kopier a1 in a3
    
    if( a1 == a2 )
      cout << "a1 und a2 gleicher Inhalt.";
    

    Tja, das ist C++. 😃


  • Administrator

    rüdiger schrieb:

    @Dravere
    Dein Ansatz ist bereits falsch. Du versuchst C in C++ zu programmieren. Das ist falsch. Vergiss C und programmier C++. In C++ benutzt man zB eher std::vector oder std::tr1::array, anstelle sich um die Speicherverwaltung zu kümmern. Wenn man dir nun sagt, das man mit new calloc ersetzen kannst, wirst du vermutlich weiterhin C in C++ programmieren, nur eben mit new anstelle calloc...

    Stimmt irgendwie schon ^^
    Aber trotzdem würde man halt manchmal gern, auch in C++ plötzlich ein memset machen oder sowas. Da wäre es angenehm, wenn man eben äquivalente Lösungen kennt 😉

    @Artchi,
    I love you ... eeeeh ... nein, also nicht wirklich ... aber vielen Dank 😃

    @vista,
    Auch danke 😉
    O..o Ich sage einem VISTA danke, meine Welt stürzt ein 😃

    Grüssli



  • Dravere schrieb:

    Aber trotzdem würde man halt manchmal gern, auch in C++ plötzlich ein memset machen oder sowas. Da wäre es angenehm, wenn man eben äquivalente Lösungen kennt 😉

    Warum ist das so? Weil du vorher C programmiert hast? Genau aus dem Grund ist es nicht gut, wenn man mit C anfängt, wenn man eigentlich C++ programmieren will.

    Ich habe z.B. in meinem Leben noch nie malloc, realloc oder so benutzt. Ich mußte gestern abend sogar wegen diesem Thread erstmal nachschauen was calloc() überhaupt ist! 🙄 Habe ich zum erstmal gehört.



  • Ich habe z.B. in meinem Leben noch nie malloc, realloc oder so benutzt. Ich mußte gestern abend sogar wegen diesem Thread erstmal nachschauen was calloc() überhaupt ist! Habe ich zum erstmal gehört.

    ...musste ich auch 🤡


  • Administrator

    Artchi schrieb:

    Dravere schrieb:

    Aber trotzdem würde man halt manchmal gern, auch in C++ plötzlich ein memset machen oder sowas. Da wäre es angenehm, wenn man eben äquivalente Lösungen kennt 😉

    Warum ist das so? Weil du vorher C programmiert hast?

    Nein, ich drücke mich daher mal anderst aus, vielleicht kommst dann dahinter, was ich gemeint habe:
    Es kommt manchmal vor, dass man einen Speicherbereich mit 0s füllen möchte.
    Da fragt man sich halt, wie man dies in C++ macht. Ich kenne da halt zufälligerweise das memset von C und würde dies verwenden, da ich bis anhin, dass std::fill nicht kannte. Jemand der bis anhin nur C++ programmiert hat, der kommt auch auf die Idee, dass er ein Array mit 0s füllen möchte, doch der kennt dann eben schon das std::fill.

    Verstanden? ^^

    Grüssli



  • Drave! Meine Frage war nicht schlecht gemeint. Wollte nur wissen, ob du C vorher gemacht hast, da viele gesagt bekommen, das man vorher C lernen soll (was natürlich nicht zu empfehlen ist). Egal, jedenfalls kann ich dir nur als Tip für die Zukunft geben: lerne die C++-Standardlibrary, dann wirst du hoffentlich bald vom C-Style weg kommen. Man muß die C++-Stdlib nicht auswendig lernen (Kann ich auch nicht), aber wenn man darüber gelesen hat wie sie arbeitet und deren Konzepte, und die Standard-Algorithmen (reverse, sort, fill, find usw.), wird man diese auch eher benutzen.

    Wie gesagt, es ist meine Empfehlung und kein Vorwurf.



  • Artchi schrieb:

    Um noch der Vollständigkeit wegen, die C++ Features zu zeigen:

    using std::tr1::array; // alternativ boost::array
    
    // 10er int-Array
    array<int,10> a = { { 1, 2, 3, 4, 5 } };
    
    // 4er String-Array
    array<std::string,4> seasons = {
            { "spring", "summer", "autumn", "winter" }
    };
    
    // 2D-Array mit Strings:
    array<array<std::string,4>,2> seasons_i18n = {
            { { { "spring", "summer", "autumn", "winter", } },
              { { "Fruehling", "Sommer", "Herbst", "Winter" } }
            }
    }
    

    Ein bisschen viele Geschweiften Klammern 🙂 Hätte man das nicht so machen können, dass man weniger Klammern benutzt, oder was steckt dahinter ?


Anmelden zum Antworten