Hallo,
in meinem Programm funktionert das kopieren des strings irgendwie nicht,
obwohl der Rückgabe Wert der sprintf() richtig ist, an was könnte das
liegen???
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):
Vielen Dank für euere Antwort.
aber das mit dem festen Array möchte ich nicht, weil die Anzahl der
Zeichen im String ist variable, ich glaube mit malloc wird auch
funktionieren???
> ich glaube mit malloc wird auch funktionieren???
Schon, aber Du musst malloc vor dem Aufruf von sprintf aufrufen, um
einen ausreichend langen Puffer anzufordern.
Sicherheitshalber solltest Du übrigens snprintf verwenden, dem wird
als zweites Argument die Länge des Puffers übergeben, was "buffer
overflows" vermeiden hilft.
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??
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.
Hallo,
ich benutze jetzt einen Fifo aus Zeiger (char*).
1
intmain()
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ß
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
>intmain()
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
voidfoo()
2
{
3
charText[]="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.
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...
> 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.