Forum: PC-Programmierung memcpy stürtzt immer ab


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Marcel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe ein Problem, dass meine memcpy-funktion unter windows10 immer 
abstürzt
Das hier momentan eh noch null raus kommt ist mir klar. Das array wird 
an einer anderen stelle beschrieben. Aber ob 0 oder andere Werte, das 
Problem bleibt, dass es abstürzt.
Auch komme ich nicht außerhalb des arrays. 500+64=564, array ist aber 
2000 lang.


file 1
// ADDRESS_BASE = 500;
// GROESSE_TABELLE = 64;
// uint8 destination[64]
readData(ADDRESS_BASE, &destination[0], GROESSE_TABELLE); 

file 2
sint32 readData (uint32 addr_u32, uint32 *data_pu32)
{
    sint32 err_s32;

    err_s32 = dataInput(&addr_u32, (uint8*) data_pu32, sizeof(uint32));

    return err_s32;
}

file 3
uint8 data[2000] = {0};

sint32 dataInput(uint32 *src, uint8 *dest, uint16 bytes_u16)
{
        memcpy( dest, &data[*src], bytes_u16);
}

von Programmierer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Marcel schrieb:
> readData(ADDRESS_BASE, &destination[0], GROESSE_TABELLE);

Marcel schrieb:
> sint32 readData (uint32 addr_u32, uint32 *data_pu32)

Da passt was nicht zusammen. readData nimmt 2 Parameter, aber du 
übergibst 3?

Warum debuggst das Programm nicht einfach mal? Setze einen Breakpoint 
auf das memcpy und überprüfe die Parameter.

von Nick M. (muellernick)


Bewertung
0 lesenswert
nicht lesenswert
Marcel schrieb:
> &addr_u32

K.A. was dabei rauskommt, wenn man die Adresse eines Parameters haben 
will. Jedenfalls nicht das Gewünschte.

von Programmierer (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Programmierer schrieb:
> Da passt was nicht zusammen. readData nimmt 2 Parameter, aber du
> übergibst 3?

PS: Und der 2. Parameter ist uint32 *, aber du übergibst uint8_t*. Das 
darf so gar nicht kompilieren. Was sind sint32 und uint32 eigentlich für 
komische Typen? Die gibt's in C und C++ gar nicht.

von Programmierer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nick M. schrieb:
> K.A. was dabei rauskommt, wenn man die Adresse eines Parameters haben
> will.

Die Adresse des Werts auf dem Stack. Das funktioniert schon. Wobei man 
sich schon fragt, warum das überhaupt als Pointer an dataInput übergeben 
wird.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Mit den Codefragmenten und den fehlenden Definitionen ist das arg schwer 
nachvollziehbar. Und es ist vermutlich auch nicht der Code, den du in 
deinem Programm probiert hast, denn du übergibst beim Aufruf von 
readData() drei Argumente, aber die Funktion hat nur zwei Parameter.

von Marcel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Programmierer schrieb:
> Marcel schrieb:
>> readData(ADDRESS_BASE, &destination[0], GROESSE_TABELLE);
>
> Marcel schrieb:
>> sint32 readData (uint32 addr_u32, uint32 *data_pu32)
>
> Da passt was nicht zusammen. readData nimmt 2 Parameter, aber du
> übergibst 3?

Ja, da ist wohl was durcheinander gekommen

file 2.c
int32 readData(uint32 addr_u32, uint8 *data_pu8, uint16 size_u16)
{
    sint32 err_s32;

    err_s32 = dataInput(addr_u32, data_pu8, size_u16);

    return err_s32;
}

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Programmierer schrieb:
> Nick M. schrieb:
>> K.A. was dabei rauskommt, wenn man die Adresse eines Parameters haben
>> will.
>
> Die Adresse des Werts auf dem Stack. Das funktioniert schon. Wobei man
> sich schon fragt, warum das überhaupt als Pointer an dataInput übergeben
> wird.

Ja, da wird erst der Wert übergeben, dann die Adresse des Parameters 
genommen, an eine weitere Funktion übergeben, die ihn dann wieder 
dereferenziert. Auch die Wahl der Datentypen wirkt etwas konfus. Da ist 
z.B. destination ein Array aus uint8, wird aber per Zeiger auf uint32 
übergeben, nur um dann in der Funktion wieder auf uint8* gecastet und 
als solcher weitergegeben zu werden.

von Programmierer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Marcel schrieb:
> err_s32 = dataInput(addr_u32, data_pu8, size_u16);

Das funktioniert nicht. dataInput will einen Pointer als 1. Parameter.

Einzelne Code-Fragmente copy-pasten oder gar abschreiben bringt nichts. 
Reduziere dein tatsächliches Programm auf das minimale Programm, welches 
exakt das Problem hat, und zeige exakt das gesamte Programm, welches 
wir dann selbst ausprobieren und prüfen können. Sonst ist das hier nur 
Rätselraten.

https://stackoverflow.com/help/minimal-reproducible-example

von Nick M. (muellernick)


Bewertung
0 lesenswert
nicht lesenswert
Was du mit dem ADDRESS_BASE machst ist komplett wirr.
Es ist keine Adresse, sonder ein Index. Und von dem Index nimmst du die 
Adresse (die auf den Stack zeigt) und dort kopierst du hin. Also auf den 
Stack. Das muss abstürzen.

von Markus K. (markus-)


Bewertung
0 lesenswert
nicht lesenswert
Marcel schrieb:
> // ADDRESS_BASE = 500;
> // GROESSE_TABELLE = 64;
> // uint8 destination[64]
> readData(ADDRESS_BASE, &destination[0], GROESSE_TABELLE);

Wie wird die "ADDRESS_BASE" verwaltet? Du kannst nicht einfach Speicher 
an beliebigen Stellen belegen, sondern musst ihn vorher mit malloc (C) 
oder mit new (C++) anfordern. Diese Funktionen geben Dir dann eine 
Adresse zurück und da darfst Du dann reinschreiben.

von Rolf M. (rmagnus)


Bewertung
1 lesenswert
nicht lesenswert
Stimmt, in dem neuen Codefragment ist plötzlich alles anders.
Also, bitte ein minimales, aber vollständiges Beispiel, das genau so 
den von dir beobachteten Absturz zeigt, posten. Mit den jetzigen Angaben 
kann man einfach nichts anfangen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.