Grüß euch alle,
bei einem (nur bei diesem Codeausschnitt) habe ich ein Laufzeitproblem.
Der Code befindet sich im Anhang.
In meinen zwischenspeicher_array, welches maximal 4 Zeichen groß ist
(nicht sichtbar im Codeschnitt) wird aus einen Empfangspuffer einer UART
eine Zahl von 0-255 gespeichert.
Wird aber (wenn das überhaupt passiert) eine Zahl im dreistelligen
Bereich, wie 100 auf einmal als PWM Signal signal in mein
zwischenspeicher_array gespeichert, stürzt der µC ab.
Die Position der ersten Ziffer ist im Puffer "2", die zweite Ziffer "3",
die dritte Ziffer "4".
Der Buchstabe P ist das Zeichen an Position "1".
bei den Löschen (also das Array komplett leeren) habe ich ein Problem,
weil das Array den zuvorherigen Speicherwert annimmt. Veilleicht liegt
es daran.
Hab das Array erst mit
zwischenzustand_array[ZWISCHENZUSTAND_ARRAY_SIZE]={0}; versucht zu
löschen.
Das Problem war noch da.
Dann hatte ich versucht mit zwischenzustand_array[0]='\0' das array zu
löschen, indem ich ein Stringende zeichen vortäusche, was aber das
Problem nicht behoben hat.
Könnte mir jemand bitte einen Anreiz geben?
Gast
#3869445
wie ist ZWISCHENZUSTAND_ARRAY_SIZE definiert?
Peter II schrieb: > wie ist ZWISCHENZUSTAND_ARRAY_SIZE definiert? Mit einen #define ZWISCHENZUSTAND_ARRAY_SIZE 4
Gast
#3869453
Tho Wes schrieb: > Peter II schrieb: >> wie ist ZWISCHENZUSTAND_ARRAY_SIZE definiert? > > Mit einen #define ZWISCHENZUSTAND_ARRAY_SIZE 4 gut, dann ist der Fehler in den code den wir nicht sehen.
danke dir peter, das reicht schon für eine gute Antwort aus. Aber wie lösche ich eigentlich (also inhalte löschen) ein Array in C, das dann komplett neu befüllt werden soll, liege ich da wenigstens richtig? Mfg, tommyProg
> zwischenzustand_array[ZWISCHENZUSTAND_ARRAY_SIZE] = { 0 };
Das ist Quatsch. Du brauchst entweder:
1 | |
oder
1 | |
a[0]=0; a[1]=0; a[2]=0; a[3]=0; Alles andere ist muehsamer, dauert laenger
Gast
#3869480
Eric B. schrieb: >> zwischenzustand_array[ZWISCHENZUSTAND_ARRAY_SIZE] = { 0 }; > > Das ist Quatsch. Du brauchst entweder: warum sollte das Quatsch sein?
Gast
#3869491
Peter II schrieb: > warum sollte das Quatsch sein? Weil es halt Quatsch ist. Lies ein C-Buch.
Siebzehn Zu Fuenfzehn schrieb: > a[0]=0; > a[1]=0; > a[2]=0; > a[3]=0; > Alles andere ist muehsamer, dauert laenger Auf jeden Fall ist es wartungsintensiver wenn sich am Array was ändert. Ohne es hier grad überprüfen zu können: Mich würde es wundern wenn der Compiler bei einem hinreichend kleinem Array die Schleife, die sich irgendwo in memset befinden wird, nicht eh durch explizites Setzen jedes Bytes ersetzt.
Tho Wes schrieb: > Aber wie lösche ich eigentlich (also inhalte löschen) ein Array in C, In der Regel garnicht. Wenn man einen Datenstream empfängt, erfolgt dies nach einem Protokoll, damit man das Ende eines Frames erkennen kann. Bei Textdaten fügt man in der Regel ein 0-Byte an und übergibt den String dann zur Auswertung. Bei Binärdaten übergibt man zusätzlich die Länge des Datenfeldes, da dieses ja auch 0-Bytes enthalten kann. Es gibt also nirgends den Zustand, daß vorher etwas gelöscht werden muß.
Gast
#3869501
Was ist überhaupt "löschen"?
Gast
#3869513
Ich lösche Arrays nicht im Betrieb, ich setzt nur meinen Pointer zum ein-/ auslesen neu und überschreibe.
Der ganze Ansatz, erst mal die einlaiufenden Zeichen in einem weiteren char-Array zwischenzuspeichern, bis ein nicht-digit daher kommt, und das ganze dann atoi vorzuwerfen, ist schon Quatsch. Eine Zahl wird um die jeweils nächste Stelle erweitert, indem man die Zahl mal 10 nimmt und dann die nächste Ziffer addiert. Genau mit diesem Mechanismus hängt man zb an die Zahl 86 die nächste Ziffer 5 an: 86 * 10 macht 860. da dann noch die 5 addiert, ergibt 865 Sobald du das Kommando erkannt hast: setzt die eine entsprechende int-Variable auf 0 für jedes weitere erkannte Zeichen, welches zur Ziffer gehört, wird dann die Zahl entsprechend um diese Ziffer erweitert
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
kein Mensch muss da Character umkopieren. Kostet nur Zeit und man läuft Gefahr Arrays zu überlaufen. Man könnte auch atoi direkt auf den Empfangsbuffer ansetzen
1 | |
2 | |
denn atoi macht ja grundsätzlich auch nichts anderes. In der eigenständigen Schleifenversion hat man den Vorteil, dass man auf eventuelle Fehler noch besser reagieren könnte, während man bei atoi erst mal am Ergebnis nicht ablesen kann, ob da zb überhaupt eine 'Zahl' im String enthalten war. Dafrü kann atoi selbstverständlich mit einem '-' umgehen, was man der Schleifenversion erst noch beibringen müsste, wenn das relevant ist. Dafür kann man die Schleifenversion in einer etwas 'auseinander genommenen' Version auch wunderbar in einer Statemachine unterbringen.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
Du hast da wieder zielsicher die komplizierteste Lösung rausgesucht.
Gast
#3869519
Bitte einen Namen eingeben (nicht "Gast") oder ein schrieb im Beitrag #3869491: > Peter II schrieb: >> warum sollte das Quatsch sein? > > Weil es halt Quatsch ist. Lies ein C-Buch. habe ich, dort steht drin das damit das ganze Array mit 0 initialisiert wird.
Gast
#3869522
Peter II schrieb: > dort steht drin das damit das ganze Array mit 0 initialisiert > wird. Ganz sicher nicht.
Gast
#3869526
Bitte einen Namen eingeben (nicht "Gast") oder ein schrieb im Beitrag #3869522: > Peter II schrieb: >> dort steht drin das damit das ganze Array mit 0 initialisiert >> wird. > > Ganz sicher nicht. doch ganz sicher. Eventuell sollte du mal nachlesen. Dort wo etwas über Initialisierung von Array steht.
Peter II schrieb: > Bitte einen Namen eingeben (nicht "Gast") oder ein schrieb im Beitrag > #3869522: >> Peter II schrieb: >>> dort steht drin das damit das ganze Array mit 0 initialisiert >>> wird. >> >> Ganz sicher nicht. > > doch ganz sicher. Vorsicht. Wortwahl. Das kann keine Initialisierung sein, weil hier keine Definition eines Arrays vorliegt. Das ist eine ganz normale Zuweisung.
Gast
#3869531
Peter II schrieb: > doch ganz sicher. Nein. Du verwechselst eine Initialisierung mit einer Zuweisung. Hier handelt es sich um eine Zuweisung. Und die ist, wenn überhaupt gültig, außerhalb des Arrays.
Gast
#3869535
Karl Heinz schrieb: > Vorsicht. Wortwahl. > > Das kann keine Initialisierung sein, weil hier keine Definition eines > Arrays vorliegt. Das ist eine ganz normale Zuweisung. oh, sorry mein fehler. Ich hatte [c] uint8_t zwischenzustand_array [ZWISCHENZUSTAND_ARRAY_SIZE] = { 0 } [\c] für mich gelesen.
Eric B. schrieb: >> zwischenzustand_array[ZWISCHENZUSTAND_ARRAY_SIZE] = { 0 }; > > Das ist Quatsch. Du brauchst entweder: > >
1 | |
> oder >
1 | |
2 | |
Eric, das funktioniert beides nicht. Das andere probiere ich noch aus.
Peter Dannegger schrieb: > In der Regel garnicht. > > Wenn man einen Datenstream empfängt, erfolgt dies nach einem Protokoll, > damit man das Ende eines Frames erkennen kann. > Bei Textdaten fügt man in der Regel ein 0-Byte an und übergibt den > String dann zur Auswertung. > Bei Binärdaten übergibt man zusätzlich die Länge des Datenfeldes, da > dieses ja auch 0-Bytes enthalten kann. > Es gibt also nirgends den Zustand, daß vorher etwas gelöscht werden muß. Oh ok. Dieses Schema muss ich auch befolgen. Zuerst habe ich ein 0-Byte (startbyte), den String habe ich auch. Aus diesen String muss ich aber gewisse Zeichen rauslesen, und diese Zeichen sind mein Wert für das PWM signal. Mfg, tommyProg
Bitte einen Namen eingeben (nicht "Gast") oder ein schrieb im Beitrag
#3869501:
> Was ist überhaupt "löschen"?
In meinem Fall würde ich sagen, die Inhalte des Arrays komplett durch
00ler verschieben, und anschließend das stringende Zeichen auf die 0te
Position ganz links setzen.
Das würde ich jetzt übrigens auch ausprobieren, vielleicht liegt es am
Stringende Zeichen.
Übrigens, ich hatte das Programm schon fertig, in einen
Zustandsautomaten, dort lief es einwandfrei, und ich musst weder was
ändern, noch ein Stringende zeichen hinzufügen.
Nur ist es mit ca. 15 Zuständen nicht besonders komfortabel lesbar.
Mfg (und noch am ausprobieren)
tommyProg
Siebzehn Zu Fuenfzehn schrieb: > a[0]=0; > a[1]=0; > a[2]=0; > a[3]=0; Mit der Methode funktioniert es auch nicht.
So, also ich habe nun ein Stringende Zeichen bei den passenden Stellen ergänzt, und nun funktionieren wenigstens die Werte von 1-99 einwandfrei und überschreiben sich nichtmehr. Code im Anhang. Die 4te Position habe ich allerdings noch nicht belegt. Nun, höchstwahrscheinlich ist genau da der Fehler. Ich muss ihn sagen, dass, wenn die 5te Position keine Zahl ist, schreibe ein Stringende Zeichen auf die 3te Position meines Arrays (4.stelle). Danke Karl übrigens für die Idee, den unteren Code mit
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
kann ich aber garnicht lesen, ich weiß nicht zu 100% Sicherheit, was das if da auf meine Laufzeit bewirkt. (das schaue ich aber demnächst auch mal an, weil es schon viel kürzer ist) Aktuell prüfe ich jetzt noch mal die 5te stelle des arrays. Danke übrigens euch allen für die schnellen Antworten ;) Mfg, tommyProg
Tho Wes schrieb: > So, also ich habe nun ein Stringende Zeichen bei den passenden Stellen > ergänzt, und nun funktionieren wenigstens die Werte von 1-99 einwandfrei > und überschreiben sich nichtmehr. > > Code im Anhang. > > Die 4te Position habe ich allerdings noch nicht belegt. > Nun, höchstwahrscheinlich ist genau da der Fehler. > Ich muss ihn sagen, dass, wenn die 5te Position keine Zahl ist, schreibe > ein Stringende Zeichen auf die 3te Position meines Arrays (4.stelle). > > Danke Karl übrigens für die Idee, den unteren Code > mit >
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
> > kann ich aber garnicht lesen, ich weiß nicht zu 100% Sicherheit, was das > if da auf meine Laufzeit bewirkt. (das schaue ich aber demnächst auch > mal an, weil es schon viel kürzer ist) Aktuell prüfe ich jetzt noch mal > die 5te stelle des arrays. > Danke übrigens euch allen für die schnellen Antworten ;) > > Mfg, > tommyProg So, also die Überprüfung auf die Stelle habe ich nun implementiert und getestet, und nun läufts einwanfrei, nur muss ich es noch vereinfachen. Da hatte ich mal so eine schöne for-schleife... Ehm, eine Frage von der Logik her: Bei einem Zustandsautomaten mit 15 (fast einzelnen Zuständen) musste ich kein Stringende zeichen auf die jeweilige Position einfügen, und das Programm lief enormst stabil. Nun ist es so, dass ich ein Stringende Zeichen einfügen muss, wenn ich 12 Zustandsautomaten zu einen "reinen" programmcode mache. Warum ist das so? mfg, tommyProg
Peter II schrieb: > Eric B. schrieb: >>> zwischenzustand_array[ZWISCHENZUSTAND_ARRAY_SIZE] = { 0 }; >> >> Das ist Quatsch. Du brauchst entweder: > > warum sollte das Quatsch sein? Weil man ein einzelnes Element ausserhalb vom Array nicht ein komplettes Array zuweisen soll.
Tho Wes schrieb: > case ExpectCommand: > if( c = 'P' ) > { > state = ExpectPWMNumber; > PWMValue = 0; > ... > [/c] > > kann ich aber garnicht lesen, ich weiß nicht zu 100% Sicherheit, was das > if da auf meine Laufzeit bewirkt. Das ist auch ein Fehler, der dem Tippen im Forum geschuldet ist. Da sollte eigentlich ja auch
1 | |
stehen :-) Und wegen Laufzeit. Ganz ehrlich: Bei dem Käse, den du da zusammenprogrammierst, solltest du dir um Laufzeit überhaupt noch keine Sorgen machen. Denn egal was du als Alternative machst, noch schlimmer kann man das schon fast nicht mehr programmieren.
> Das ist auch ein Fehler, der dem Tippen im Forum geschuldet ist. > Da sollte eigentlich ja auch >
1 | |
2 | |
> stehen :-) > Und wegen Laufzeit. > Ganz ehrlich: Bei dem Käse, den du da zusammenprogrammierst, solltest du > dir um Laufzeit überhaupt noch keine Sorgen machen. Denn egal was du als > Alternative machst, noch schlimmer kann man das schon fast nicht mehr > programmieren. Okay, das sehe ich als kompliment an, weil dann heißt das ja, dass ich nurnoch besser werden kann xD. Aber warum muss ich die Stringende Zeichen seperat ergänzen, wenn ich einen Zustandsautomaten "aufspalte"?
Tho Wes schrieb: > Aber warum muss ich die Stringende Zeichen seperat ergänzen, wenn ich > einen Zustandsautomaten "aufspalte"? Du musst das Stringende IMMER ergänzen, wenn du einen String aus einzelnen Zeichen zusammensetzt! Es sei denn in den Zeiten, die du zusammensetzt ist das Stringende-'\0' schon mit drinn. Trotzdem wird man eher auf Nummer sicher gehen. Die paar Taktzyklen kosten nichts. > Okay, das sehe ich als kompliment an, weil dann heißt das ja, dass > ich nurnoch besser werden kann xD. Nimms nicht tragisch. Mein erster Sortieralgorithmus war auch furchtbar. Kryptisch, komplex unwartbar und wenn der Mond günstig gestanden ist, hat er sogar funktioniert. Allerdings hab ich dann schnell gelernt, wie man sowas richtig macht. Lange bevor ich mein erstes richtiges Projekt begonnen habe. Aber das macht nichts. Selbst für ein Übungsprogramm war er fuchtbar, kryptisch und unwartbar - sprich inakzeptabel. Nachdem ich gesehen habe, wie man sowas richtig und vernüftig angeht, war mir auch klar, dass mir noch viel fehlt, ehe ich an ein echtes Projekt auch nur denken kann.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.