sprintf() und char*

#709194
Lesenswert?

dein ar ist ein zeiger, der nicht initialisiert ist. Daher überschreibst 
dein sprintf Speicherbereiche, die nicht dafür reserviert sind.
Besser so (Speicher für den String reservieren und die Adresse des 
Speicherbereichs dem sprintf geben):
1
char ar [5];
2
int tmp = 0;
3
tmp = sprintf(&ar[0],"test"); // tmp ist dann 4
4
oder 
5
tmp = sprintf(ar,"test"); // tmp ist dann 4
Gast #709295
Lesenswert?

ist es eigentlich üblich in der uC-Welt (im Vergleich zum PC) mit malloc 
und delete zu arbeiten, was dann automatisch heisst mit dem Heap??

nächste Frage:
ine meinem Programm möchte ich viel text über die UART verschicken, so 
eine Art diagnose beim Starten oder bei fehler...., was macht ihr denn 
so in dem Fall? ich glaube nicht dass man in einer Funktion wartet bis 
das ganze Array gesendet ist, kann ja vielleicht ein paar ms dauern??
Persönliche Seite #709520
Lesenswert?

malloc und delete passen sowieso nicht zusammen.

new und delete  (C++)

malloc und free (C)

Nein, üblicherweise verzichtet man in Situationen mit insgesamt wenig 
Arbeitspeicher auf dynamische Speicherverwaltung - Stichworte wären da 
"Speicherfragmentierung", "Verwaltungsaufwand".

Die zweite Aufgabe erledigt man i.d.R. mit einem interruptgesteuerten 
Senden - d.h. der auszugebende Text wird in einen (globalen) Puffer 
eingetragen, und ein Interrupthandler, der von der UART ausgelöst wird, 
wenn sie ein Zeichen übertragen hat, überträgt quasi "im Hintergrund" 
den Inhalt dieses Puffers.

Man muss hierbei natürlich vor dem erneuten Befüllen des Puffers 
überprüfen, ob dieser wieder zur Verfügung steht, also der gesamte 
Inhalt versendet wurde.
Arbeitet man mit einem FIFO als Puffer-Organisation, können neue Zeichen 
in den Puffer eingetragen werden, sobald welche von der Interruptroutine 
"abgeräumt" wurden. Beim Eintragen ist also der Fifo-Füllstand zu 
überprüfen und gegebenenfalls zu warten.
Gast #712070
Lesenswert?

Hallo,

ich benutze jetzt einen Fifo aus Zeiger (char*).
1
int main()
2
{
3
putsUART("Hallo");
4
.
5
.
6
.
7
}
8

9
putsUART(char* str)
10
{
11
fifo[index].ptr = str; //Das Senden erfolgt in der ISR
12
index++;
13
.
14
.
15
.}

1- wird das funktionieren, oder werden die Daten irgendwann mal 
überschrieben(bei verschiedener String-Länge??
2- bis wann bleibt "Hallo" im Speicher, oder wann wird der Speicher von 
"Hallo" wieder frei?

Danke für die Infos

Gruß
#712088
Lesenswert?

Stefen wrote:
> Hallo,
>
> ich benutze jetzt einen Fifo aus Zeiger (char*).

Obacht.
Pointer in Datenstrukturen kann gefährlich sein.
So ein Pointer muss ja irgendwohin zeigen um nützlich
zu sein. Wenn das wohin er zeigt, aber out of scope
geht, dann hast du einen Pointer der in den Wald zeigt.

>
1
> int main()
2
> {
3
> putsUART("Hallo");
4
> .
5
> .
6
> .
7
> }
8
> 
9
> putsUART(char* str)
10
> {
11
> fifo[index].ptr = str; //Das Senden erfolgt in der ISR
12
> index++;
13
> .
14
> .
15
> .}
16
>
>
> 1- wird das funktionieren,

Das wird funktionieren. Und zwar deshalb, weil der
Scope eines String Literals das komplette Programm ist.
D.h. dieser konstante String wird beim Programmstart
erzeugt und überlebt, bis das Programm terminiert.

> oder werden die Daten irgendwann mal
> überschrieben(bei verschiedener String-Länge??

Da wird nichts überschrieben.

> 2- bis wann bleibt "Hallo" im Speicher, oder wann wird der Speicher von
> "Hallo" wieder frei?

Sollte jetzt auch schon klar sein.


Aber
das hier
1
void foo()
2
{
3
  char Text[] = "Test";
4
  putsUART( Text );
5
}

das kann und wird wahrscheinlich grauslich schief gehen.
Der Scope von Text ist die Funktion foo. Nachdem foo()
verlassen wurde, existiert die Variable Text nicht mehr.
Daran ändert auch nichts, dass innerhalb putsUART ein
Pointer auf diese Variable gespeichert wurde.
#712093
Lesenswert?

Stefen wrote:

> putsUART("Hallo");

Ich meine irgendwo mal gelesen zu haben, das solch statische Strings vom 
Startup-Code ins SRAM kopiert werden, wenn sie vom Programmcode mit 
normalem char-pointer referenziert werden.

Eine andere Möglichkeit wäre, sie über das PROGMEM- Prefix Byteweise vom 
Flash ins SRAM zu holen.

Diese Info ist allerdings schon etwas älter; ich weiss nicht, ob sich da 
mitlerweile was getan hat...
#712153
Lesenswert?

Stefen wrote:
> d.h. bei:
>
1
> int main()
2
> {
3
>   while(1)
4
>   {
5
>     putsUART("messwert");
6
>   }
7
> .
8
> .
9
> .
10
> }
11
>
> wird der Speicher irgendwann mal voll?

Meinst du das fifo Array. Ja sicher, irgendwann ist das
Array gefüllt.

Oder zielst du auf "messwert" ab?
"messwert" wird ja nur einmal 'erzeugt'. Nämlich dann wenn
das Programm hochkommt. Für das Programm existiert der
konstante String "messwert" ganz einfach sobald main()
die Kontrolle bekommt. Der ist schon da. Es gibt ihn
nur ein einziges mal.

Am Anfang schuf Gott, äh die Runtime, den String "messwert".
Und die Runtime sah, dass es gut war. Und der Programmierer
sprach: lass uns einen Pointer auf diesen String unendlich
oft im fifo Array ablegen. Doch das fifo Array murmelte
in seinen langen, weißen Bart: Ich kann nicht beliebig viele
Pointer aufnehmen. Mein Programmierer hat mich nur mit einer
begrenzten Kapazität ausgestattet. Aber ich befolge das
Gebot: Du sollst den Code deines Programmierers ausführen.

Da weinte die Runtime bitterlich und nachdem die Kapazität´
des Arrays erschöpft war geschahen seltsame Dinge.
So wurde am Ende der ersten Millisekunde
der 'Out of bounds'-Error erfunden. Und die Runtime sah nicht,
dass es nicht gut war, weil sie sich um Out of bounds Error
nicht kümmerte.

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