wenn ich nun mit dieser arbeite wird im Laufe des Programms ein anderer
Wert in diese geladen. Es gibt allerdings keinerlei zuweisung im
Programm. Deklariere ich sie mit einem Anderen Wert außer 0 funktioniert
das Programm einwandfrei. Woran kann das liegen?
Danke euch
Michael S. schrieb:> Woran kann das liegen?
An deinem Programm.
> Es gibt allerdings keinerlei zuweisung im> Programm
Woher weisst du das? hast du dein Projekt schonmal nach "c" durchsucht?
Du wirst dich wundern wo es überall "c"s gibt in deinem Programm.
Variablennamen mit nur einem Buchstaben zu erzeugen ist mehr als
unglücklich, da es nichts über die Variable aussagt.
Michael S. schrieb:> Es gibt allerdings keinerlei zuweisung im Programm.
(Warum ist es dann überhaupt eine Variable und keine Konstante?)
> Deklariere ich sie mit einem Anderen Wert außer 0 funktioniert> das Programm einwandfrei. Woran kann das liegen?
Wie bereits geschrieben irgendwo ein Overflow.
Mit "richtigen" Daten initialisierter Speicher liegt in der .data
Section, genullter dagegen in .bss.
Dadurch ergibt sich auch ein anderer Adressbereich für deine Variable:
initialisierst du sie mit null, liegt sie direkt neben dem Speicher, in
dem du den Overflow produzierst. Initialisierst du sie mit was anderem,
liegt sie (relativ) weit davon weg und wird deshalb nicht überschrieben.
Gemessen an der Fragestellung ist eine Reihe von Fehlern möglich und
wahrscheinlich.
Leider sind zu wenig Details vorhanden, um die Möglichkeiten
einzugrenzen. Es empfiehlt sich daher den Code zu posten. Falls das ein
Code ist, den Du im Netz gefunden und abgewandelt hast, poste bitte auch
einen Link auf den Originalcode zusätzlich.
sie wird im Programm mehrmals aufgerufen und abgefragt jedoch nicht mehr
beschrieben. Trotzdem erhält sie einen anderen inhalt. Jetzt habe ich
bemerkt dass das Programm an anderer stelle auch solch einen Fehler hat.
Vielleicht sollten wir hier mal Anfangen. Ich Poste die Positionen mal
ein.
1
intschalter_stellung_vortakt[10];// Deklaration in global.c
2
3
//weiter geht es in der schalter.c
4
externintschalter_stellung_vortakt[10];//externer Aufruf in schalter.c
In Diesem Programmabschnitt funktioniert alles einwandfrei. ausser der
Schalter an PA6. Hier wird in der variablen schalter_stellung_vortakt[3]
der wert 1 nicht in den Speicher übergebenund in der nächsten Rude steht
nochmal der Wert 2 da. Die Zuweisung mit 1 ist mit der Pinabfrage doch
eindeutig. Diese Variable wird auch im weitern Programm nicht mehr
aufgerufen.
Danke euch
Michael S. schrieb:> Hier wird in der variablen schalter_stellung_vortakt[3]> der wert 1 nicht in den Speicher übergebenund in der nächsten Rude steht> nochmal der Wert 2 da.
Liegt das vllt dran, dass
Max H. schrieb:> Liegt das vllt dran, dass~PINA & (1<<PA3)false ist und der Code im else> ausgeführt wird?
Im Debug wird der Code richtig ausgeführt und es wird die jeweils
richtige Schleife aufgerufen ohne das Else. Der Debug bleibt an der
Richtigen stelle stehen zeigt die richtigen Werte in den Variablen an,
welche Transferiert werden sollen. Beim nächsten SChritt sind die Werte
aber nicht übergeben worden. Im Memory bleibt der alte Wert bestehen.
falsch sein sollte, werden alle anderen Zuweisungen in den
If-Anweisungen vorher überschrieben.
Es steht zu vermuten, dass hier noch "else" nach den If-Anweisungen
fehlen und dass die Zuweisungen im letzten else-Zweig jeweils einzeln in
diese else-Zweige gehören.
Allerdings ist das nur eine Vermutung, denn es fehlen uns Angaben
darüber wie das Programm funktionieren soll.
Ich werde nur dann antworten wenn Beschreibung und vollständiger Code
vorliegen.
Max H. schrieb:>> richtige Schleife aufgerufen> Welche Schleife? Poste besser den kompletten Code.
Die Richtige IF-Anweisung wird aufgerufen und bearbeitet. Das ist der
Komplette Code für die Variable.
Michael S. schrieb:> Max H. schrieb:>>> richtige Schleife aufgerufen>> Welche Schleife? Poste besser den kompletten Code.>> Die Richtige IF-Anweisung wird aufgerufen und bearbeitet. Das ist der> Komplette Code für die Variable.
OK. Damit ist die Frage für mich erledigt.
Michael S. schrieb:> Max H. schrieb:>>> richtige Schleife aufgerufen>> Welche Schleife? Poste besser den kompletten Code.> Die Richtige IF-Anweisung wird aufgerufen und bearbeitet.
Das ist aber keine Schleife.
> Das ist der Komplette Code für die Variable.
Wenn du nicht irgendwo einen wilden Pointer hast, dann muss es die
Zuweisung im else sein.
Wieso hast du chalter_stellung_vortakt dann in der global.c und nicht in
der schalter.c als static deklariert?
Aber dein else-Block wird auch immer ausgeführt, wenn nicht die letzte
if-Bedingung zutrifft. Das wird kaum so gewollt sein. Haben aber schon
viele erwähnt und du ignorierst es beharrlich und besteht darauf, dass
alles korrekt ist. Wenn dem so wäre, hättest du aber kein Fehlverhalten.
Also hast du nun einen Fehler oder stimmt alles? Fragen stellen und dann
die Antworten nicht hören wollen...
Den wesentlichen Hinweis auf den Unterschied zwischen .data und .bss
hast du auch ignoriert, der den Unterschied zwischen 0 und anderem Wert
erklärt und dabei den Verdacht erhärtet, dass der Speicher deiner
Variablen von einem Buffer- oder Stackoverflow korrumpiert wird.
Variablen kann man nicht aufrufen.
Klaus schrieb:
> falsch sein sollte, werden alle anderen Zuweisungen in den> If-Anweisungen vorher überschrieben.>> Es steht zu vermuten, dass hier noch "else" nach den If-Anweisungen> fehlen und dass die Zuweisungen im letzten else-Zweig jeweils einzeln in> diese else-Zweige gehören.
Du hast Recht, else if war hier die lösung.
Das Programm läuft jetzt einwandfrei. Ich hab die else if vergessen.
Das Problem schalter_stellung_vortakt ist also vom Tisch nicht aber das
erste.
Peter II schrieb:> vermutlich ein Speicherüberschreiber im Programm (buffer Overflow) oder> der Stack reicht nicht.foo schrieb:> Mit "richtigen" Daten initialisierter Speicher liegt in der .data> Section, genullter dagegen in .bss.
Dann werde ich nun hier mal ansetzen.
Michael S. schrieb:> Im Debug wird der Code richtig ausgeführt und es wird die jeweils> richtige Schleife aufgerufen ohne das Else. Der Debug bleibt an der> Richtigen stelle stehen zeigt die richtigen Werte in den Variablen an,> welche Transferiert werden sollen. Beim nächsten SChritt sind die Werte> aber nicht übergeben worden. Im Memory bleibt der alte Wert bestehen.
Bei so einfachen Code kann der Debugger einen schonmal bezüglich der
Position narren. Du müßtest es schon mit einer anderen Methode
verifizieren. Dass eine Variablenzuweisung nicht funktioniert würde
schon auf das Gegenteil hinweisen.
Steffen R. schrieb:> Du müßtest es schon mit einer anderen Methode> verifizieren. Dass eine Variablenzuweisung nicht funktioniert würde> schon auf das Gegenteil hinweisen.
Kannst du mir etwas genauer erklären was du meinst? Welche andere
Methode der Zuweisung meinst du? Ein Buffer Overflow wird doch meist
durch standart funktionen wie beispielsweise strcpy() herforgerufen
welche hier aber keine Anwendung haben. Oder wo habe ich noch mit einem
Buffer oder Stack overflow zu rechnen?
Steffen R. schrieb:> Michael S. schrieb:>> Im Debug wird der Code richtig ausgeführt und es wird die jeweils>> richtige Schleife aufgerufen ohne das Else. Der Debug bleibt an der>> Richtigen stelle stehen zeigt die richtigen Werte in den Variablen an,>> welche Transferiert werden sollen. Beim nächsten SChritt sind die Werte>> aber nicht übergeben worden. Im Memory bleibt der alte Wert bestehen.>> Bei so einfachen Code kann der Debugger einen schonmal bezüglich der> Position narren. Du müßtest es schon mit einer anderen Methode> verifizieren.
Prinzipiell richtig.
Nur denke ich, dass er sich selber ein Ei gelegt hat. Er hat sich im
Debugger an dieser Stelle
1
...
2
if...
3
{
4
...
5
}
6
7
if....
8
{
9
....// <--------------- zb hier
10
}
11
12
if....
13
{
14
....
15
}
16
else
17
{
18
....
19
}
die Zuweisung angesehen und gesehen, dass die auch gemacht wird. Dass er
den Wert später im else noch einmal überschreibt, weil die letzte
Bedingung eben nicht zugetroffen hat, das hat er nicht gesehen, weil er
mit dem Debugger gar nicht dorthin gesteppt ist.
Denn wenn er das getan hätte, dann hätte ihm sein Fehler selbst
auffallen müssen.
Stimmts Michael?
Michael S. schrieb:> Oder wo habe ich noch mit einem> Buffer oder Stack overflow zu rechnen?
- Zu viele verschachtelte Unterprogramme
- Rekursive Funktionen
- Wenn man mit Pointerarithmetik arbeitet, kann man leicht irgendwo
hinschreiben wo man nicht will wenn man nicht aufpasst
- Wenn man über ein Array interiert und ein paar Indizes zu weit geht.
genau dafür gibt es die ++ und -- Operatoren!
Damit man sich nicht einen Wolf tippt und auf einen Blick sieht, dass
die Variable links vom = und die Variable rechts vom = ein und dieselbe
ist!
Ausserdem verhindert das Tippfehler, weil man den Variablennamen nicht 2
mal anführen muss, sondern nur einmal.
Einfacher zu verstehen in der Analyse ist es auch, weil man keine
Buchstabenwüste danach absuchen muss, ob da jetzt wirklich links und
rechts vom = dieselbe Variable steht.
Und ja. Man kann es mit der Länge von Variablennamen auch übertreiben!
Michael S. schrieb:> Steffen R. schrieb:>> Du müßtest es schon mit einer anderen Methode>> verifizieren. Dass eine Variablenzuweisung nicht funktioniert würde>> schon auf das Gegenteil hinweisen.>> Kannst du mir etwas genauer erklären was du meinst? Welche andere> Methode der Zuweisung meinst du? Ein Buffer Overflow wird doch meist> durch standart funktionen wie beispielsweise strcpy() herforgerufen> welche hier aber keine Anwendung haben. Oder wo habe ich noch mit einem> Buffer oder Stack overflow zu rechnen?
Es ging mir darum, die Aussage zu relativieren, dass der Debugger den
korrekten Programmablauf zeigt.
Speziell Sprünge werden gern mal selbst bei abgeschaltetem Optimierer
ungünstig angezeigt.
Karl H. schrieb:> ie Zuweisung angesehen und gesehen, dass die auch gemacht wird. Dass er> den Wert später im else noch einmal überschreibt, weil die letzte> Bedingung eben nicht zugetroffen hat, das hat er nicht gesehen, weil er> mit dem Debugger gar nicht dorthin gesteppt ist.
Du magst recht haben.
Aber ich hätte schon erwartet, dass man bei dem Probelm -> Variable wird
mit 2 überschrieben - und es gibt nur eine offizielle Stelle - dass man
dort wenigstens mal einen Breakpoint hinsetzt und schaut, ob man dort
vorbei kommt.
Oder wenigstens die gesamte Funktion debugged.
Steffen R. schrieb:> Aber ich hätte schon erwartet
hätte ich auch.
Michael muss scheinbar noch lernen, dass Programmfehlverhalten in >99.5%
aller Fälle auf Fehler im Programm zurückzuführen sind. Für einen
Anfänger ist es eben verführerisch, dem Compiler die Schuld in die
Schuhe schieben zu wollen. Die Hoffnung stirbt eben zuletzt und
praktisch nirgendwo sonst ist diese Hoffnung so trügerisch wie in der
Programmierung.
Zum aktuellen Stand:
Karl H. schrieb:> Stimmts Michael?
Hallo Karl. Ja, dass hier die else bei den if´s fehlen haben wir schon
gesehen und geändert.
Um im Wirrwar ein wenig auf zu räumen die derzeitige aktuelle
Fragestellung nochmal:
im Programm wird eine Variable deklariert:
anschließend wird die hier_ist_die_variable nur noch in Anweisungen
ausgelesen. Wenn die hier_ist_die_variable mit dem Wert 1 deklariert
wird klappt das Programm. Wenn ich mit einer 0 deklariere wird ein
Fremder, vielleicht früherer Wert in die Variable geladen.
Derweilen will ich auf stack oder buffer overflow prüfen. Doch wird mit
dieser Variablen eben nicht mit Standartfunktionen gearbeitet wie z.B.
strcp()...
Michael S. schrieb:> Du hast Recht, else if war hier die lösung.
Das glaub ich allerdings nicht.
Zeig mal her, wie du das geändert hast. Ich wette, dass deine Lösung
keine Lösung ist.
> Das Programm läuft jetzt einwandfrei.
Kann ich mir nicht vorstellen. Du testest einfach nur schlecht.
"else if" hört sich verdächtig an. Denn die Tasten sollen ja alle
einzeln behandelt werden.
Kennt nicht jemand nen netten kalten Eisbär, der bei mir vorbei kommen
könnte?
Michael S. schrieb:> ausgelesen. Wenn die hier_ist_die_variable mit dem Wert 1 deklariert> wird klappt das Programm. Wenn ich mit einer 0 deklariere wird ein> Fremder, vielleicht früherer Wert in die Variable geladen.
Und es wurde schon gesagt:
Der dafür zuständige Fehler kann quer durch das Programm überall
stecken.
> Derweilen will ich auf stack oder buffer overflow prüfen.
Dann tu das. Konzentrier dich erst mal auf buffer overflows und
kontrolliere alle Arrayzugriffe
> Doch wird mit> dieser Variablen eben nicht mit Standartfunktionen gearbeitet wie z.B.> strcp()...
PS: Es heisst 'Standard', mit weichem D.
Eine Standart wäre die Art zb eines Verkaufsstandes. Oder mit viel
Phantasie "die Kunst zu stehen". Beides ist in diesem Zusammenhang nicht
richtig. Denn das Wort schreibt sich Standard.
Ingo L. schrieb:> Michael S. schrieb:>> Woran kann das liegen?> An deinem Programm.>>> Es gibt allerdings keinerlei zuweisung im>> Programm> Woher weisst du das? hast du dein Projekt schonmal nach "c" durchsucht?> Du wirst dich wundern wo es überall "c"s gibt in deinem Programm.
Also wenn man ordentliche IDEs verwendet, wie z.B. Eclipse, kann man die
Variable markieren und findet mit "Open call hierarchy" sofort alle
Stellen wo diese Variable benutzt wird.
Geht das im Atmel Studio etwa nicht?
Max H. schrieb:
Ist jetzt mehr an Michael zum Nachdenken gerichtet.
(Ich leih mir nur jetzt deinen Code aus, weil er kürzer ist)
Wobei:
> if(fallende_flanke_pina & (1 << PA6)) //Schalter 3> {> schalter_stellung = 3;> benutzereingabe_temperatur_soll_wert--;> }
Hier könnte man sich das Setzen von schalter_stellung auf 3 auch sparen.
Es spielt sowieso keine Rolle, denn entweder ist
> if(fallende_flanke_pina & (1 << PA3)) //Schalter 4
PA3 betätigt, dann ...
> schalter_stellung = 4;
... wird die Variable auf 4 gesetzt. Oder PA3 ist nicht betätigt ....
> else> {> schalter_stellung = 5;
... dann wird die Variable auf 5 gesetzt.
Sei es wie es sei, auf jeden Fall behält die Variable nicht ihren Wert
von 3. Am Ende der Funktion ist die Variable auf jeden Fall entweder 4
oder 5. Aber auf keinen Fall mehr 3. Egal was an PA6 passiert ist.
Michael S. schrieb:> Wenn ich mit einer 0 deklariere wird ein> Fremder, vielleicht früherer Wert in die Variable geladen.
Wann?
Thema .bss und .data war schon aufgeführt.
Schreib-Breakpoints setzen, wenn dies bei Dir möglich ist. Dann wird
automatisch angehalten, wenn auf die Variable geschrieben wird.
Michael S. schrieb:> Doch wird mit> dieser Variablen eben nicht mit Standartfunktionen gearbeitet wie z.B.> strcp()...
irrelevant.
Ob du den Fehler nun direkt machst oder den Standardfunktionen
fehlerhafte Parameter übergibst macht keinen Unterschied.
Karl H. schrieb:>> Derweilen will ich auf stack oder buffer overflow prüfen.>> Dann tu das. Konzentrier dich erst mal auf buffer overflows und> kontrolliere alle Arrayzugriffe
Und um den Stack erstmal auszuschließen erhöhe diesen erstmal großzügig.
Anm:
Ich äußer mich mal nicht mit Verbesserungsvorschlägen. Ich habe manchmal
den Eindruck, dass diese gut gemeinten Hinweise der Grund sind, dass die
Fragesteller so zurückhaltend mit ihrem Sourcecode sind.
Karl H. schrieb:> Für einen> Anfänger ist es eben verführerisch, dem Compiler die Schuld in die> Schuhe schieben zu wollen. Die Hoffnung stirbt eben zuletzt und> praktisch nirgendwo sonst ist diese Hoffnung so trügerisch wie in der> Programmierung.
Zumindest so lange, bis man sich das Assembler-Listing anschaut (und
auch versteht ;))
Steffen R. schrieb:> Schreib-Breakpoints setzen, wenn dies bei Dir möglich ist. Dann wird> automatisch angehalten, wenn auf die Variable geschrieben wird.
Hallo,
also ich habe den Breakpoint auf die Variable gesetzt. Mit Erfolg.
Fehler gefunden.
Danke für die Zeit.
Hallo
Steffen R. schrieb:> Es wäre nett gewesen auch dazuzuschreiben, wer von uns am besten orakeln> konnte.
Wer von euch am besten ist macht mal unter euch aus, aber....
Ich habe wie vorgeschlagen die Variable selbst beobachtet. Dabei ist der
Breakpoint pointer auf einer X-beliebigen Stelle stehen geblieben. Beim
betrachten ist mir aufgeallen, dass eine andere Variable, die mit dieser
Variablen nichts zu tun hat, falsch deklariert war. Nachdem diese nun
richtig deklariert ist lief alles reibungslos. Ich glaube es war ein
char Anstelle einer int bzw double.
Danke euch nochmals
Michael