malloc, strncpy auf STM32F4 keine Funktion

OP #3244410
Lesenswert?

Hallo, bei mir zeigt strncpy keine Wirkung! Zuerst dachte ich, es liegt 
an der newlib. Bin aber mittlerweile am steppen im dissasembly und dort 
ist hinter strncpy eine Funktionalität hinterlegt. Es werden auch die 
Adressen der Strings geladen und auch das zu schreibende Zeichen kann 
ich erkennen. Jedoch passiert an der Stelle (strb.w r5, [r4], #1), an 
der das Zeichen in den neuen String kopiert werden sollte nichts. Das 
disassembly ist angefügt. Der Code lautet
1
  const char* from = "12345678";
2
  char *to = "yyyyyy";
3
  strncpy(to, from+2, 5);

Was läuft falsch?
Angehängte Dateien:
OP #3244464
Lesenswert?

OK, Lösung gefunden:

Wenn ich schreibe
1
char to[6];
 dann wird die Variable irgendwo im RAM angelegt und kann verändert 
werden. Wenn ich aber schreibe
1
char to = "yyyyyy";
 dann wird die Variable irgendwo im Flash angelegt und kann nicht 
verändert werden.

Warum ist das so und wie kann ich festlegen, welche Variable ich wohin 
haben möchte?
#3244476
Lesenswert?

Marcel F. schrieb:
> OK, Lösung gefunden:
>
> Wenn ich schreibe
>
1
> char to[6];
2
>
> dann wird die Variable irgendwo
> im RAM angelegt und kann verändert werden.

Logisch. Genau das hast du ja auch mit dem Array ausgedrückt.
1
   to
2
   +---+---+---+---+---+---+
3
   |   |   |   |   |   |   |
4
   +---+---+---+---+---+---+
schreibst du auch noch eine Initialisierung dazu, dann wird der Speicher 
auch gleich noch auf definierte Werte gesetzt.
1
char to[6] = "abcd";
1
   to
2
   +---+---+---+---+---+---+
3
   | a | b | c | d | \0|   |
4
   +---+---+---+---+---+---+

> Wenn ich aber schreibe
>
1
> char* to = "yyyyyy";
2
>
> dann wird die Variable irgendwo im Flash angelegt
> und kann nicht verändert werden.

Auch logisch.
Die Pointer Variable liegt im SRAM. UNd dieser Pointer wird so 
eingerichtet dass er auf ein String-Literal (eine konstanter String) 
zeigt. Denn "yyyyy" ist eine Stringkonstante und für dich unveränderbar.
1
   to
2
   +-----+
3
   | o------------------->"yyyyy"
4
   +-----+
und da String-Literale per Definition unveränderbar sind, darf sie der 
Compiler auch in Speicher legen, der vom Programm aus nicht veränderbar 
ist.
Du könntest den Pointer auf was anderes zeigen lassen, wenn du willst
1
  char* to = "yyyyyy";
1
   to
2
   +-----+
3
   | o-------------------->"yyyyy"
4
   +-----+     
5
                
6
                    "Hallo Du, Copyright by me"
1
  to = "Hallo Du, Copyright by me";
1
   to
2
   +-----+
3
   | o---------+           "yyyyy"
4
   +-----+     |
5
               |
6
               +--->"Hallo Du, Copyright by me"
aber das ändert nichts daran, dass auch dieses Stringliteral "Hallo Du, 
Copyright by me" ein Stringliteral und als solches unveränderbar ist.


Der Compiler darf sogar soweit gehen und mehrere derartige Verweise zu 
einem einzigen zusammenführen. Denn wie gesagt: Die String-Konstante ist 
für dich ja tabu, kann sich also daher während eines Programmlaufs nicht 
verändern.
1
  char* to = "yyyy";
2
  char* to2 = "yyyy";
1
   to
2
   +-----+
3
   | o------------------->"yyyyy"
4
   +-----+                 ^
5
                           |
6
                           |
7
   to2                     | 
8
   +-----+                 |
9
   | o---------------------+
10
   +-----+
OP #3244498
Lesenswert?

OK, danke für die ausführliche Erklärung. Hab lange nichts mit Strings 
in C gemacht, daher war mir das nicht bewusst. Ich dachte, dass
1
char var[3]="abc"
 und
1
char* var = "abc"
 das gleiche ist :)

Ach und ja, es sollte außerdem
1
char var[4]="abc"
 heißen, damit die Null noch reinpasst ;)
#3244509
Lesenswert?

Marcel F. schrieb:

> Ach und ja, es sollte außerdem
>
1
> char var[4]="abc"
2
>
> heißen, damit
> die Null noch reinpasst ;)

es sollte eigentlich
1
char var[] = "abc";
heißen. Denn dann zählt der Compiler für dich den String ab und 
dimensioniert das Array gerade groß genu, dass der String mit allem drum 
und drann gerade noch reinpasst.

Wenn du allerdings dann da mit einem strncat noch was hinten drann 
hängen willst, dann bist DU dafür verantwortlich, dass das Array dafür 
auch groß genug ist.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren