Memcpy



  • Schurke schrieb:

    //---------------------------------------------------------------------------
     
    #pragma hdrstop
    #include <string.h>
    #include <iostream.h>
    //---------------------------------------------------------------------------
    

    - du kannst hier im Forum die [ cpp]-Tags benutzen (ohne Leerzeichen dazwischen)- mit farbigem Syntaxhighlighting und damit besser lesbar 🙂
    - <string.h> und <iostream.h> sind seit ca. 10 Jahren veraltet (der aktuelle Standard ist von '98) benutz stattdessen <string> (bzw. in deinem Fall <cstring>) und <iostream> etc.

    Schurke schrieb:

    int Input[] = {0, 1, 3, 5, 7, 9, 0};//7
    int Output[7];
    char Buffer[100];
    memset(Buffer,0,100);
    memset(&Output,0,4*7);
    

    - als automatische Variablen sind Buffer und Output meines Wissens eh schon mit 0 initalisiert, damit sind die memset-aufrufe überflüssig.
    - davon abgesehen bezeichnet Output schon den pointer auf den Anfang des Arrays, &Output ist damit fehlerhaft und sollte dir um die Ohren fliegen
    - selbst wenn es nötig wäre, die Arrays zu initialisieren, ist memset C und kein C++. Das C++-pendant nennt sich fill:

    #include <algorithm>
    //...
    int Output[7];
    char Buffer[100];
    std::fill(Output, Output+7, 0);
    std::fill(Buffer, Buffer+100, 0);
    

    Schurke schrieb:

    for ( int i = 0; i < sizeof(Input)/sizeof(int); i++){
      memcpy(Buffer+(i*sizeof(int)), &Input[i]+(i*sizeof(int)), sizeof(int));
      }
    for ( int i = 0; i < sizeof(Output)/sizeof(int); i++){
      memcpy(&Output[i]+(i*sizeof(int)), Buffer+(i*sizeof(int)), sizeof(int));
      }
    

    - memcpy ist wieder C, nicht typsicher und spätestens bei non-PODs wird sowas krachen (gilt übrigens auch für memset). Eine C++-Version hiervon würde lauten:

    assert(sizeof(Input) < sizeof(Buffer)); //man kann ja nie wissen...
    char* bufferend = std::copy( reinterpret_cast<char*>(Input),
              reinterpret_cast<char*>(Input+7),
              Buffer );
    *bufferend = '\0'; //bufferend und diese zeile sind eigentlich unnötig, da eh nullinitialisiert, das hier schließt den C-String auf jeden Fall ab.
    
    std::copy(Input, Input + 7, Output);
    

    Schurke schrieb:

    funktioniert noch nicht so wie ichs mir dachte

    Schurke schrieb:

    erziele ich jetzt noch nicht das gewollte Ergebnis ...

    Wenn du nicht erzählen magst wie das gewollte Ergebnis aussieht bzw. was du dir gedacht hast (und was stattdessen rausgekommen ist), dann wird dir niemand richtig helfen können...



  • for ( int i = 0; i < sizeof(Input)/sizeof(int); i++){
      memcpy(Buffer+(i*sizeof(int)),((char*)&Input[i])+(i*sizeof(int)), sizeof(int));
      }
    for ( int i = 0; i < sizeof(Input)/sizeof(int); i++){
      memcpy(((char*)&Output[i])+(i*sizeof(int)),Buffer+(i*sizeof(int)), sizeof(int));
     }
    

    memcpy erwartet char* bei der quelle und beim ziel



  • Vernichtend... Trotzdem Danke, sehr ausführlich



  • Hallo,

    pumuckl schrieb:

    als automatische Variablen sind Buffer und Output meines Wissens eh schon mit 0 initalisiert, damit sind die memset-aufrufe überflüssig.

    Nein, das ist nicht der Fall, automatische Variablen werden nicht initialisiert.

    MfG,

    Probe-Nutzer



  • int Output[7] = { };
    char Buffer[100] = { };
    

    Jetzt sind sie mit 0 initialisert 😉


  • Mod

    BorisDieKlinge schrieb:

    memcpy erwartet char* bei der quelle und beim ziel

    nein.



  • Wie gesagt, memcpy() und memset() sind C und haben ihre entsprechenden Probleme (eben bei komplexeren Klassen). Die Header <string.h> und <iostream.h> waren im Übrigen nie C++-Standard.

    Zu C++: Benutz die STL und deren Container. Dann kannst du dir auch die sizeof -Orgien sparen.


  • Mod

    <string.h> ist und war schon immer Teil des ANSI-C Standards, gehört mithin auch zu C++. Dessen Pendant ist im Übrigen <cstring> und nicht <string>. Woher nimmst du sonst die Deklarationen für memcpy&co?


  • Administrator

    camper schrieb:

    <string.h> ist und war schon immer Teil des ANSI-C Standards, gehört mithin auch zu C++. Dessen Pendant ist im Übrigen <cstring> und nicht <string>. Woher nimmst du sonst die Deklarationen für memcpy&co?

    Wie hat man eigentlich den C++ Header <string> vorher genannt? <iostream> war <iostream.h> und wie ist es mit <string>, wenn <string.h> schon von ANSI C besetzt ist?

    Grüssli



  • camper schrieb:

    <string.h> ist und war schon immer Teil des ANSI-C Standards, gehört mithin auch zu C++. Dessen Pendant ist im Übrigen <cstring> und nicht <string>. Woher nimmst du sonst die Deklarationen für memcpy&co?

    Stimmt, da hast du Recht. Ich habe wohl zu wenig genau geschaut.

    Aber die Frage von Dravere würde mich auch interessieren.

    Die Header der C++-Bibliothek mit .h (z.B. <iostream.h>) waren ja bei MSVC 6 aufgekommen... Wieso gibt es die immer noch? Abwärtskompatibilität?


Anmelden zum Antworten