Variablendeklaration mit Wert "0" befüllen, Prog in C, Atmega 32, AtmelStudio 6_2

OP #4190251
Lesenswert?

Hallo,

ich habe eine Variable
1
C-int c = 0; //deklariert.

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
#4190262
Lesenswert?

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.
Gast #4190268
Lesenswert?

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.
Gast #4190321
Lesenswert?

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.
OP #4190334
Lesenswert?

Hallo und Danl der vielen Antworten.

Um eins vorweg zu nehmen, die Konstante hat einen eindeutigen Namen
1
 int long variable_die_ich_jetzt_mal_variable_nenne = 0;

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
int schalter_stellung_vortakt[10];  // Deklaration in global.c
2

3
//weiter geht es in der schalter.c
4
extern int schalter_stellung_vortakt[10]; //externer Aufruf in schalter.c
5

6
 int schalter()
7
 {
8
    int schalter_stellung = 3;
9
   
10
    if (~PINA & (1<<PA6)&&(schalter_stellung_vortakt[3] == (2)))              //Schalter 3
11
    {
12
      schalter_stellung = 3;
13
          benutzereingabe_temperatur_soll_wert =benutzereingabe_temperatur_soll_wert -0x01;
14
    }
15
    if (~PINA & (1<<PA3)&&(schalter_stellung_vortakt[4] == (2)))              //Schalter 4
16
    {
17
      schalter_stellung = 4;
18
      benutzereingabe_temperatur_soll_wert =benutzereingabe_temperatur_soll_wert +0x01;
19
    }
20
     else
21
     {
22
      schalter_stellung = 5;   
23
  
24
     }
25
   return schalter_stellung;
26
 }
27

28
 void entprellung_taster()
29
 {
30
  if (~ PINA & (1<<PA2))              //Schalter 1
31
  {
32
    schalter_stellung_vortakt[1]=1;
33
  }
34
  if (~PINA & (1<<PA4))              //Schalter 2
35
  {
36
    schalter_stellung_vortakt[2]=1;
37
  }
38
  if (~PINA & (1<<PA6)  )          //Schalter 3
39
  {
40
    schalter_stellung_vortakt[3]=1;
41
  }
42
  if (~PINA & (1<<PA3))              //Schalter 4
43
  {
44
    schalter_stellung_vortakt[4]=1;
45

46
  }
47
  else
48
  {
49
    schalter_stellung_vortakt[1]=2;
50
    schalter_stellung_vortakt[2]=2;
51
    schalter_stellung_vortakt[3]=2;
52
    schalter_stellung_vortakt[4]=2;
53
  }
54
   
55
 }

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
OP #4190350
Lesenswert?

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.
Gast #4190356
Lesenswert?

Falls diese Bedingung
1
if (~PINA & (1<<PA3))

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.
#4190365
Lesenswert?

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?
#4190374
Lesenswert?

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.
OP #4190393
Lesenswert?

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.
#4190395
Lesenswert?

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.
OP #4190414
Lesenswert?

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?
#4190421
Lesenswert?

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?
#4190428
Lesenswert?

Michael.
Schreib sowas
1
          benutzereingabe_temperatur_soll_wert =benutzereingabe_temperatur_soll_wert -0x01;

doch um Himmels Willen als
1
          benutzereingabe_temperatur_soll_wert --;

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!
#4190434
Lesenswert?

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.
#4190437
Lesenswert?

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.
OP #4190444
Lesenswert?

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:
1
z.B int long hier_ist_die_variable = 0; 
2

3
//im laufe des Programmes wird der Wert aus:
4

5
int variable_mit_wert = 1400; 
6

7
//an diese übergeben mit:
8

9
hier_ist_die_variable = variable_mit_wert;    //geladener Wert = 1400
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()...
#4190452
Lesenswert?

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.
#4190470
Lesenswert?

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?
#4190475
Lesenswert?

Da die Taster an alle an PORTA sind könnte man das auch so machen, spart 
Speicher und Rechenzeit.

1
//Untested
2
static uint8_t pina_old = 0xFF;
3

4
uint8_t schalter()
5
{
6
  uint8_t schalter_stellung = 3;
7
  uint8_t fallende_flanke_pina = ~PINA & pina_old;
8
  
9
  if(fallende_flanke_pina & (1 << PA6))              //Schalter 3
10
  {
11
    schalter_stellung = 3;
12
    benutzereingabe_temperatur_soll_wert--;
13
  }
14
  if(fallende_flanke_pina & (1 << PA3))              //Schalter 4
15
  {
16
    schalter_stellung = 4;
17
    benutzereingabe_temperatur_soll_wert++;
18
  }
19
  else
20
  {
21
    schalter_stellung = 5;   
22
  }
23
  return schalter_stellung;
24
}
25

26

27
void entprellung_taster()
28
{
29
  pina_old = PINA;   
30
}
#4190505
Lesenswert?

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.
#4190649
Lesenswert?

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.
OP #4220476
Lesenswert?

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

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