none
memcpy 0xC0000005: Zugriffsverletzung beim Lesen ander Position 0x00667000 RRS feed

  • Frage

  • Hallo Leute,

    Ich habe ein kleines Problem mit memcpy und weiß einfach nicht, wie ich das Problem lösen kann!

    Ich sende Daten über Ethernet und rufe dabei bei jedem Paket, das gesendet werden soll folgenden Code auf:

    void WriteLabel(char* data, int size){
    binaryPackage *write = (binaryPackage*) malloc(sizeof(binaryPackage));
    
    memcpy(write->pkg, data, sizeof(write->pkg));
    write->pkgSize = size;
    
    writePacket(*write);
    
    free(write);
    }
    

    binaryPackage ist ein struct und in writePacket(*write) wird das struct an den darunterliegenden Thread übergeben, der die Daten sendet.

    Das Problem ist, dass der Aufruf der Methode immer unterschiedlich oft gelingt!
    Teilweise bis zu 10 mal, teilweise aber nur 4 mal.

    memcpy löst dann folgenden Fehler aus:

    Unbehandelte Ausnahme bei 0x72C70E9A (msvcr110d.dll) in SendData.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00667000

    Dabei wird memcpy.asm geöffnet und bleibt bei der letzten Zeile der nachfolgend angegebenen stehen:

    CopyUp:
    ;
            ; See if Enhanced Fast Strings is supported.
            ; ENFSTRG supported?
            bt      __favor, __FAVOR_ENFSTRG
            jnc     CopyUpSSE2Check                 ; no jump
            ;
            ; use Enhanced Fast Strings
            rep     movsb
    

    Ich frage mich nun, warum memcpy hier einen Fehler wirft, und warum es unterschiedlich oft gelingt!

    Ich hoffe ihr könnt mir helfen!

    Liebe Grüße

    Anna

    Montag, 10. November 2014 10:23

Antworten

  • Habs hinbekommen!!! =)

    War leider n echt blöder Fehler von mir :/

    Ab und zu wurden weniger Bytes versendet, d.h. "data" war kleiner.

    Ich war der Ansicht, man gibt bei memcpy als letzten Parameter (write.pkgSize) die Größe an, die in write.pkg hineinpasst, und nicht die Größe, die "data" beinhaltet.

    Deswegen habe ich immer einen Fehler bei memcpy bekommen weil der Speicher der copiert werden solle außerhalb der Variable "data" war und ich darauf keinen Zugriff hatte!

    Trotzdem vielen Dank für eure Hilfe! =)

    Grüße

    Anna

    • Als Antwort markiert Anna_Bauer21 Dienstag, 11. November 2014 11:16
    Dienstag, 11. November 2014 09:13

Alle Antworten

  • Hi,

    da Du den Parameter "size" beim Kopieren der Daten ignorierst, nehme ich an, dass dieser Wert erheblich kleiner als "sizeof(write->pkg)" ist. Des weiteren gibt es hier nicht wirklich einen Grund für malloc/free. Aus der kalten Hose heraus würde ich sagen:

    void WriteLabel(char* data, int size){
    binaryPackage write;
    write.pkgsize = min(size, sizeof(write.pkg));
    memcpy(write.pkg, data, write.pkgsize);
    writePacket(&write);
    }
    
    

    Montag, 10. November 2014 11:07
  • Hallo Rene,

    danke für deine Antwort!
    Ich wusste gar nicht, dass man hier auch ohne Speicherreservierung arbeiten kann, vielen Dank dafür! =)

    Aber leider ist das Problem nicht behoben.

    Ich habe gerade memmove getestet, wo ich genau das gleiche Problem habe!

    Was mir noch aufgefallen ist, ich habe vor dem Aufruf von WriteLabel() ein Sleep(100) stehen, wenn ich dieses entferne, wird beim zweiten Paket schon ein Fehler geworfen. Wenn ich die Zeit erhöhe, bleibt der Fehler allerdings gleich!

    Kann es sein, dass memcpy bei schnellem hintereinander aufrufen irgendwas verhaut?

    Viele Grüße

    Anna



    Montag, 10. November 2014 11:29
  • Hallo Anna,

    da beim Erstellen des Objektes write die Größe von binaryPackage::pkg nicht bekannt ist, kannst du binaryPackage::pkg im Konstruktor eigentlich ja nur mit nullptr initialisieren, oder? (Hat dein stuct überhaupt einen Konstruktor?)

    Hat binaryPackage keinen Konstruktor, dann zeigt binaryPackage::pkg irgendwo hin. Das Kopieren der Daten an die Adresse Write.pkg ruft dann (u.U.) eine Zugriffsverletzung hervor.

    Arnold



    Montag, 10. November 2014 17:15
  • Hallo Arnold,

    ich arbeite im aktuellen Projekt nicht mit Klassen.

    Das struct sieht folgendermaßen aus:

    typedef struct {
    	char	pkg[MAX_PKG_SIZE];
    	int		pkgSize;
    } binaryPackage;

    Wenn ich mit malloc einen Speicher reserviere, kann es doch nicht passieren, dass das struct irgendwo hin zeigt um eine Zugriffsverletzung zu erhalten oder?

    Viele Grüße

    Anna

    Dienstag, 11. November 2014 08:24
  • Habs hinbekommen!!! =)

    War leider n echt blöder Fehler von mir :/

    Ab und zu wurden weniger Bytes versendet, d.h. "data" war kleiner.

    Ich war der Ansicht, man gibt bei memcpy als letzten Parameter (write.pkgSize) die Größe an, die in write.pkg hineinpasst, und nicht die Größe, die "data" beinhaltet.

    Deswegen habe ich immer einen Fehler bei memcpy bekommen weil der Speicher der copiert werden solle außerhalb der Variable "data" war und ich darauf keinen Zugriff hatte!

    Trotzdem vielen Dank für eure Hilfe! =)

    Grüße

    Anna

    • Als Antwort markiert Anna_Bauer21 Dienstag, 11. November 2014 11:16
    Dienstag, 11. November 2014 09:13
  • (Ich dachte binaryPackage::pkg ist ein char*, dann müsstest du diesen Pointer ja initialisieren)

    Wenn der Speicherbereich binaryPackage::pkg groß genug ist um den mit memcpy kopierten Speicher aufzunehmen - und das ist er, wenn du den Code von Rene verwendest - dann kann es eigentlich nur der Pointer data sein, der auf einen Speicherbereich zeigt, den du (dein Programm) nicht lesen darfst (darf). Der Fehler liegt dann also nicht in der Funktion WriteLabel, sondern irgendwo im aufrufenden Code.

    Arnold
    Dienstag, 11. November 2014 09:57