Forum: Compiler & IDEs Pointer Vergleich mit Konstante


von Marc (gierig) Benutzerseite


Lesenswert?

Ich blick es nicht.

Habe einen Ringpuffer für die USART Behandlung.
(Studio6.1 also GCC4.7.x, ziel ist ein tiny2313)
1
#define USART_RX_BUFFER_MAX 10      
2
static uint8_t usart_rx_buffer[USART_RX_BUFFER_MAX]; 
3
static uint8_t *usart_rx_read = usart_rx_buffer;     //lese von Puffer
4
static uint8_t *usart_rx_write = usart_rx_buffer;    //schreiben von usart in buffer
1
uint8_t USART_RX_Byte(void){
2
    uint8_t temp;
3
    temp =*usart_rx_read;                                   
4
    usart_rx_read++;                                     
5
 
6
   if (usart_rx_read == usart_rx_buffer + USART_RX_BUFFER_MAX){ 
7
       usart_rx_read=usart_rx_buffer;                  
8
        }
9
    return temp;   
10
    }//end RX_BYTE

Die IF Abfrage soll also schauen wenn der ARRAY ende erreicht ist
und den Zeiger zurücksetzen. Das klappt so bei beiden TX Zeigern
und dem RX schreib Zeiger auch wunderbar

Nur hier wird das IF niemals ausgeführt und ich bekomme einen Buffer 
überlauf



Geht:
1
uint8_t USART_RX_Byte(void){
2
    uint8_t temp;
3
    temp =*usart_rx_read;                                 
4
    usart_rx_read++;                               
5
         
6
    uint8_t x = (usart_rx_read - usart_rx_buffer) 
7
    if (x ==  USART_RX_BUFFER_MAX){ //check if Buffer full now
8
       usart_rx_read=usart_rx_buffer;                  
9
        }
10
    return temp;   
11
    }//end RX_BYTE

Führe ich den Pointervergleich einzeln aus und vergleiche dann gegen
meine Konstante ist wieder alles schön.
das IF macht was es soll und mein Zeiger rennt nicht wild im Speicher 
rum.

Was läuft hier verkehrt ? Das hatte mit der ersten Version geklappt,
und diese lauft auch für die anderen drei Zeiger ohne dieses 
Fehlerverhalten. Einzige Änderung, mein Projekt ist an anderen stellen 
größer geworden...

Vermutung:
der "usart_rx_read" liegt nun ungünstig im Speicher und
der Vergleich (ptr == ptr + Konstante) ist im Prinzip schon falsch 
weil...
ja weil...falscher cast ?

von Klaus W. (mfgkw)


Lesenswert?

Ist da noch ein Interrupt beteiligt?

Dann fehlen ein paar volatile ...

von Karl H. (kbuchegg)


Lesenswert?

Marc D. schrieb:

> und diese lauft auch für die anderen drei Zeiger ohne dieses
> Fehlerverhalten. Einzige Änderung, mein Projekt ist an anderen stellen
> größer geworden...

Womit es auch die Möglichkeit gibt, dass du genau an diesen anderen 
Stellen irgendwo den Speicher niedergebügelt hast und dabei zufällig 
genau diesen einen Pointer erwischt hast.

Was du siehst sind die Symptome. Die Ursache dafür kann aber auch an 
ganz andere Stelle zu finden sein. Überprüf mal deine letzten 
Änderungen, ob du irgendwo einen Array-Overflow produziert hast, oder 
sonst irgendwie über einen ungültigen Pointer dir den Speicher 
zerschiesst.

von Marc (gierig) Benutzerseite


Lesenswert?

Schwer zu erkennen, aber nein "usart_rx_read" wird nur in dieser 
Funktion benutzt  gelesen verändert).

von Klaus W. (mfgkw)


Lesenswert?

Ein anderer Verdacht (globale Variablen sind ja immer supekt):
Evtl. änderst du usart_rx_read versehentlich noch an einer anderen 
Stelle, und der Test auf Gleichheit klappt z.B. deshalb nicht, weil der 
Wert durch ein zusätzliches Erhöhen schon über dem Vergleichswert liegt?

von Marc (gierig) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Überprüf mal deine letzten
> Änderungen, ob du irgendwo einen Array-Overflow produziert hast, oder
> sonst irgendwie über einen ungültigen Pointer dir den Speicher

Ich werde mal suchen, bzw. Rauschmeißen / reduzieren.
Wobei dann aber im Prinzip mein "FIX" auch nicht
gehen dürfte.
1
   if (usart_rx_read == usart_rx_buffer + USART_RX_BUFFER_MAX){ 
2
       usart_rx_read=usart_rx_buffer; }

Also Speicher Adresse  = Puffer Anfang + Max Buffer.
Geht nicht (ging aber und tut bei den anderen)

Meine Korrektur dazu.
1
    uint8_t x = (usart_rx_read - usart_rx_buffer) 
2
    if (x ==  USART_RX_BUFFER_MAX){ 
3
        usart_rx_read=usart_rx_buffer;  }

Also Speicher Adresse - Pufferadresse und dann vergleichen mit MAX 
Puffer.
Und schon klappt es wider wie gewünscht.

Ich verstehe nur nicht was da anders läuft , weil das Ergebnis
(also die rechen Operation) das gleiche ist.

von Klaus W. (mfgkw)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Womit es auch die Möglichkeit gibt, dass du genau an diesen anderen
> Stellen irgendwo den Speicher niedergebügelt hast und dabei zufällig
> genau diesen einen Pointer erwischt hast.

Zumal die Variable evtl. genau hinter dem Feld liegt; ein Zugriff hinter 
das Feld würde genau usart_rx_read treffen.

Womit die unsichtbare Funktion interessant wäre, die das Feld füllt...

von Marc (gierig) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Ein anderer Verdacht (globale Variablen sind ja immer supekt):
> Evtl. änderst du usart_rx_read versehentlich noch an einer anderen
> Stelle.

So global sind die auch nicht. Static gesetzt in globalen teil der C 
Datei.
damit so erstmals nur in der Datei zu erreichen. Und es ist ein  Pointer
auf ein Array. also auch keine 08/15 Variabel.

von Klaus W. (mfgkw)


Lesenswert?

Marc D. schrieb:
> So global sind die auch nicht. Static gesetzt in globalen teil der C
> Datei.
> damit so erstmals nur in der Datei zu erreichen. Und es ist ein  Pointer
> auf ein Array. also auch keine 08/15 Variabel.

Und das soll gegen versehentliches Überschreiben schützen?

Wenn du nur ein Fragment zeigst und behauptest, der Rest sei natürlich 
in Ordnung, wird man dir nicht viel helfen können.

von Karl H. (kbuchegg)


Lesenswert?

Marc D. schrieb:

> So global sind die auch nicht. Static gesetzt in globalen teil der C
> Datei.

Ist wurscht.
Sie existieren im RAM und sind damit über einen wilgewordenen Pointer 
bzw. Arrayzugriff zu erreichen.

Im Fehlerfall kannst du dich auf gar nichts mehr verlassen. Wenn 
Speicher niedergebügelt wird, kann in weiterer Folge alles mögliche 
passieren.

Variablen die unvorhersehbar ihren Wert ändern, sind meistens ein Indiz 
für sowas.

von Marc (gierig) Benutzerseite


Angehängte Dateien:

Lesenswert?

Karl Heinz Buchegger schrieb:
> Sie existieren im RAM und sind damit über einen wilgewordenen Pointer
> bzw. Arrayzugriff zu erreichen.

Ja richtig soweit auch klar, da habe ich mich nicht richtig ausgedrückt.


Geht nicht
1
   if (usart_rx_read == usart_rx_buffer + USART_RX_BUFFER_MAX){ 
2
       usart_rx_read=usart_rx_buffer; }

Geht
1
   uint8_t x = (usart_rx_read - usart_rx_buffer) 
2
    if (x ==  USART_RX_BUFFER_MAX){ 
3
        usart_rx_read=usart_rx_buffer;  }

Ich arbeite also an der gleichen stelle nur mit einer
anderen Berechnung meines Pointers auf das Daten Array.

Wenn irgendwas den Pointer verbiegen würde, das würde sich
das doch auch bei dem "geht" durchschlagen.


Klaus Wachtler schrieb:
> Wenn du nur ein Fragment zeigst und behauptest, der Rest sei natürlich
> in Ordnung, wird man dir nicht viel helfen können.
Behaupte ich nicht. sage nur das der Fehler an der von mir
angesprochenen stelle ist und durch umstellen wieder funktionsfähig ist.
aber snbei die komplette usrat.c, allerdings fehlt da die Änderung.

von Karl H. (kbuchegg)


Lesenswert?

Marc D. schrieb:

> Geht nicht
>
1
   if (usart_rx_read == usart_rx_buffer + USART_RX_BUFFER_MAX){
2
>        usart_rx_read=usart_rx_buffer; }
>
> Geht
>
1
   uint8_t x = (usart_rx_read - usart_rx_buffer)
2
>     if (x ==  USART_RX_BUFFER_MAX){
3
>         usart_rx_read=usart_rx_buffer;  }
>
> Ich arbeite also an der gleichen stelle nur mit einer
> anderen Berechnung meines Pointers auf das Daten Array.
>
> Wenn irgendwas den Pointer verbiegen würde, das würde sich
> das doch auch bei dem "geht" durchschlagen.

Nein, würde es nicht notwendigerweise.
Die beiden Codesequenzen sind nicht identisch.
im ersten Fall müssen alle 16 Bit der Pointer übereinstimmen.
Im zweiten Fall aber, wegen uint8_t x, nur die Low-Bytes.
D.h. im ersten Fall hast du eine 1:65536 Chance, dass der Vergleich 
trotz verbogenem Pointer auf Gleich plädiert. Im zweiten Fall hast du 
eine 1:256 Chance. Mit einem bischen Glück (oder Pech, je nachdem wie 
man es sieht), kann es sein, dass dir der überschriebene Pointer nicht 
weit genug davonläuft, du also nach wie vor einen Fehler im Programm 
hast, ihn aber nicht bemerkst weil es sich momentan (noch) nicht 
auswirkt.

von Klaus W. (mfgkw)


Lesenswert?

Danke für den Quelltext.

Ich wiederhole mich zwar, aber:
Wenn du Variablen in einer ISR und im Hauptthread verwendst, müssen sie 
als volatile deklariert sein.
Das sind sie bei dir nicht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Wenn du Variablen in einer ISR und im Hauptthread verwendst, müssen sie
> als volatile deklariert sein.

Außerdem müssen die Zugriffe auf Variablen größer 8 Bit (das schließt
alle Zeiger mit ein) außerhalb der ISR atomar ausgeführt werden.  Auch
das ist nicht der Fall.

von Marc (gierig) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Danke für den Quelltext.
>
> Wenn du Variablen in einer ISR und im Hauptthread verwendst, müssen sie
> als volatile deklariert sein.
> Das sind sie bei dir nicht.

Ja stimmt, wird hier aber so immer noch nicht verwendet.

Bleiben wir bei "RX_BUFFER", das ist ein ARRAY das über
zwei Pointer angesprochen wird.
Pointer in der ISR ist also ein anderer als im Hauptthread.
der Pointer und das Array sind statisch im gleichen File wie
auch die ISR Funktion. Da bedarf es kein volatile.
Macht aber auch keinen unterschied.


Damit haben wir:
usart_rx_read = ein Pointer ausschließlich in der USART_RX_Byte(void)
verwendet wird
usart_rx_buffer = das array, das in der Funktion und in der ISR
zwar ÜBER den Pointer gefüllt wird, sonst einfach nur seine Adresse
liefern soll zu verglich wo ich mich im array bin.

und ein umstellen der Berechnung die das Problem löst, mir aber nicht
klar ist was daran anders sein soll.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Marc D. schrieb:
> und ein umstellen der Berechnung die das Problem löst, mir aber nicht
> klar ist was daran anders sein soll.

Dann wirst du wohl oder übel mal den generierten Code analysieren
müssen.

von Klaus W. (mfgkw)


Lesenswert?

Nur nebenbei: dein uint8_t USART_RX_Byte() liest auch, wenn nie etwas in 
den Puffer geschrieben wurde.

von Marc (gierig) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Nur nebenbei: dein uint8_t USART_RX_Byte() liest auch, wenn nie etwas in
> den Puffer geschrieben wurde.

Im Code ist dafür oben in der Funktion eine Abfrage (Grade 
auskommentiert)

USART_RX_Byte() wird aber ausschließlich in der USRAT_Menu() aufgerufen.
Diese wiederum wird nur getriggert wenn die USART RX ISR auch ein
Byte geschrieben hat.(da wird ein Flag gesetzt) Damit ist das erst 
einmal ausgeschlossen.

Aber auch wenn, sollte hier der Pointer wieder auf array Start
gesetzt werden wenn USART_RX_BUFFER_MAX erreicht wird.


Jörg Wunsch schrieb:
> Dann wirst du wohl oder übel mal den generierten Code analysieren
> müssen.

Ich denke auch. Werde ich mich mich heute Abend mal daransetzen.

von Karl H. (kbuchegg)


Lesenswert?

Marc D. schrieb:

> und ein umstellen der Berechnung die das Problem löst, mir aber nicht
> klar ist was daran anders sein soll.


Sie 'löst' sehr wahrscheinlich das Problem nicht. Sie kaschiert es nur.
Denn deine beiden Codestücke sind eben NICHT funktional identisch! Das 
eine ist ein 16-Bit Vergleich, das andere ein 8-Bit Vergleich.

Hier
1
static uint8_t USART_RX_Byte(void){
2
  uint8_t temp;
3
//   if(usart_rx_read == usart_rx_write){          //security checks if there is a byte on read buffer DISABLE save 20Byte flash
4
//     USART_TX_Byte('F');  
5
//     return 0;
6
//     }    
7
  temp =*usart_rx_read;                  //read from ring buffer
8
  usart_rx_read++;                    //point to next byte in buffer
9
   if (usart_rx_read == usart_rx_buffer + USART_RX_BUFFER_MAX){ //check if Buffer full now  
10
      usart_rx_read=usart_rx_buffer;          //reset to buffer start address (load Pointer with buffer start address)
11
    }
12
  return temp;  
13
  }//end RX_BYTE
sollte die Manipulation von usart_rx_read unter Interrupt Sperre 
passieren, da in der ISR ebenfalls darauf zugegriffen wird.


Ich denke allerdings immer noch, dass du den falschen Baum anbellst. 
Dein eigentliches Problem ist an einer ganz anderen Stelle im Code und 
hat mit der UART nichts zu tun. Der UART Code ist nur das Symptom, an 
dem du siehst dass du einen Fehler im Programm hast.

von Amateur (Gast)


Lesenswert?

@Marc

Hättest Du Dich nicht besser gestanden, wenn Du das ganze Indiziert 
aufgebaut hättest?

Dann hättest Du einen konstanten, unveränderlichen Pufferanfang und zwei 
8-Bit Laufvariablen.

Auch würde der Zugriff wahrscheinlich schneller sein, da die meisten 
Vergleiche zwischen Bytes stattfinden und nur die "echten" Zugriffe 
Pointeroperationen wären.

Vor allem aber wäre die Arithmetik "offensichtlicher". So etwas hat 'ne 
Menge Vorteile, wenn du nächstes Jahr mal was ändern musst.

Du aber arbeitest ständig mit Pointern - wohl 16 Bit breit - und dem 
entsprechenden arithmetischen Aufwand, bei Deinem 8-Bit Prozessor.

Bei einem "echten" 16-Bit Prozessor wäre Dein Ansatz wohl schneller.

von Marc (gierig) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:

> sollte die Manipulation von usart_rx_read unter Interrupt Sperre
> passieren, da in der ISR ebenfalls darauf zugegriffen wird.

und das ist meines Erachtens falsch. usart_rx_read ist nur in der
Funktion in Verwendung nicht in der ISR.

Gemeinsamer Nenner wäre einzig das Array ,das über den Pointer
angesprochen wird. Wobei einer nur schreibt und einer nur liest.

Aber weiter oben sagst du:
> Sie 'löst' sehr wahrscheinlich das Problem nicht. Sie kaschiert es nur.
> Denn deine beiden Codestücke sind eben NICHT funktional identisch! Das
> eine ist ein 16-Bit Vergleich, das andere ein 8-Bit Vergleich.

Mhhh, das stimmt allerdings.

Bzw:

>dass du den falschen Baum anbellst.
ich mich durchaus mal auf die suche nach einen anderen Baum mache.

von Karl H. (kbuchegg)


Lesenswert?

Marc D. schrieb:

>> sollte die Manipulation von usart_rx_read unter Interrupt Sperre
>> passieren, da in der ISR ebenfalls darauf zugegriffen wird.
>
> und das ist meines Erachtens falsch. usart_rx_read ist nur in der
> Funktion in Verwendung nicht in der ISR.

Ist egal.
Es ist eine 16 Bit Einheit und kann daher als solches nicht zb in einem 
Zug inkrementiert werden.

Wechselt der Pointer von 0x00FF beim Inkrement auf 0x0100
UND
kommt der Interrupt Aufruf genau zwischen dem Inkrement des Low_bytes 
und dem Inkrement des High_bytes, dann sieht die ISR unter Umständen 
bereits das neue Low-Byte 0x00 aber immer noch das alte High-Byte 0x00. 
Die ISR benutzt also den teilinkrementierten "Zwischenstand" 0x0000 als 
Wert vom Pointer. Und der hat weder mit 0x00FF, noch mit 0x0100 etwas zu 
tun.
(Ist ein mögliches Szenario. Ich sag nicht das es so ist - aber es ist 
möglich)

Spiele nach den Regeln und du hast weniger Probleme.
Hast du Mehrbyte-Variablen UND werden die in ISR Funktionen ALS AUCH in 
nicht ISR Funktionen benutzt, dann müssen die volatile sein und der 
Zugriff muss atomar abgesichert werden.
Alles andere kann funktionieren, kann aber auch in die Hose gehen, je 
nach Umständen, die wir als C-Programmierer nicht kontrollieren können.
Ein cli() vor den 3 Zeilen Code und ein sei() danach behebt das Problem 
und kostet nicht viel, ausser dass ein möglicher Interrupt ein paar 
Taktzyklen verzögert zur Ausführung kommt, was bei einem UART Interrupt 
nun wirklich ziemlich egal ist.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wechselt der Pointer von 0x00FF beim Inkrement auf 0x0100
> UND
> kommt der Interrupt Aufruf genau zwischen dem Inkrement des Low_bytes
> und dem Inkrement des High_bytes, dann sieht die ISR unter Umständen
> bereits das neue Low-Byte 0x00

Die ISR sieht diesen Pointer nicht, hier ist es wirklich schnuppe, ob 
die ISR in den Inkrement hineinpfuscht.

Da hat Marc recht, er verwendet diesen Pointer schließlich 
ausschließlich in seiner Fifo-Lese-Routine.

von Marc (gierig) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
>> und das ist meines Erachtens falsch. usart_rx_read ist nur in der
>> Funktion in Verwendung nicht in der ISR.
>
> Ist egal.
Nein ist es nicht

> Es ist eine 16 Bit Einheit und kann daher als solches nicht zb in einem
> Zug inkrementiert werden.
Soweit klar.

> Wechselt der Pointer von 0x00FF beim Inkrement auf 0x0100
> UND
> kommt der Interrupt Aufruf genau dazwischen
> dann sieht die ISR unter Umständen bereits das neue Low-Byte 0x00 aber
> immer noch das alte High-Byte 0x00. Die ISR benutzt also den
> Zwischenstand 0x0000 als Wert vom Pointer. Und der hat weder mit 0x00FF,
> noch mit 0x0100 etwas zu tun.

Zauber ISR ? Wie sieht denn die ISR das neue LOW Byte ?
Gar nicht, den das Ding wird in der ISR nicht angefasst.
nicht berührt, nicht verändert und nicht einmal gelesen.
in der ISR wird ein Anderer Pointer benutzt der nur aufs gleiche
DATEN Array im RAM zeigt.


> Spiele nach den Regeln und du hast weniger Probleme.
Mach ich ja (meines Erachtens).
Also Warum einen zugriff Atomar gestalten wenn der
zugriff zwar unterbrochen aber nicht geänderter werden kann.

Nicht desto Trotz:

> Ein cli() vor den 3 Zeilen Code und ein sei() danach behebt das Problem
Hatte ich gestern schon gemacht (hatte auch die beteiligten Pointer
auf volatile), werde das nachher aber noch mal etwas gründlicher 
angehen.

Mein Aktueller Verdacht: um so länger ich drüber nachdenke.

Das High Byte des usart_rx_read Pointers wird Irgendwo
überrannt (du sagtest schon das wird was wild laufendes).

Indizien:
usart_rx_read wird nur in der Funktion benutz als Pointer.
TINY2313 braucht mit seinen 128Byte Ram nur den LowPart von Pointer.
Alle andere gleichartigen Abfragen funktionieren

Beweise: folgen wenn ich welche habe

von Karl H. (kbuchegg)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Karl Heinz Buchegger schrieb:
>> Wechselt der Pointer von 0x00FF beim Inkrement auf 0x0100
>> UND
>> kommt der Interrupt Aufruf genau zwischen dem Inkrement des Low_bytes
>> und dem Inkrement des High_bytes, dann sieht die ISR unter Umständen
>> bereits das neue Low-Byte 0x00
>
> Die ISR sieht diesen Pointer nicht, hier ist es wirklich schnuppe, ob
> die ISR in den Inkrement hineinpfuscht.

Moment, Hab ich mich verlesen

<studier>

Ooops.
Hab ich
1
ISR(USART_RX_vect){
2
      *usart_rx_write=UDR;                //store Data to write pointer address  
3
      usart_rx_write++;    
4
      if (usart_rx_write == usart_rx_buffer + USART_RX_BUFFER_MAX){ //check if Buffer Overflow  now        
5
          usart_rx_write = usart_rx_buffer;      //reset to buffer start Address.              
6
        }                      
7
      GPIOR0  |= (1<<USART_NEW_BYTE);            //Set FLAG for action in Mainloop      
8
  }//end WS2812_LEDCount_RX_Vect

Wieso ist da keine Prüfung auf Buffer Overflow drinnen?
(Vergleich des Read Pointers mit dem Write Pointer)

Ok. Ich nehms zurück. Da gibt es kein Problem mit atomarem Zugriff.

von Marc (gierig) Benutzerseite


Lesenswert?

> Wieso ist da keine Prüfung auf Buffer Overflow drinnen?
> (Vergleich des Read Pointers mit dem Write Pointer)

spart Platz im Flash :-), deswegen ist das auch in der Lese Funktion
ausgeklammert und hier gar nicht vorhanden.

zweites ich weiß wie viel ich in den Puffer packen kann.
und wie schnell der dann wieder entleert wird.
Der USART wird von PC über Hand befüllt....

Damit ist das also schon Optimierter Code für meine Anwendung
und keine Musterlösung für einen nach allen Seiten abgesicherter
Ringbuffer.


> Ok. Ich nehms zurück. Da gibt es kein Problem mit atomarem Zugriff.
das beruhigt mich dann auch. Nicht das ich noch anfange mein
quasi frisches wissen selber in frage zu stellen.

von Paul (Gast)


Lesenswert?

Marc D. schrieb:
> Damit ist das also schon Optimierter Code für meine Anwendung


Naja, Optimierung sieht für mich anders aus.

> und keine Musterlösung für einen nach allen Seiten abgesicherter
> Ringbuffer.

Der aber deutlich übersichtlicher, kürzer und schneller wäre.

von Marc (gierig) Benutzerseite


Lesenswert?

Paul schrieb:


> Naja, Optimierung sieht für mich anders aus.

Wie denn ?


>> und keine Musterlösung für einen nach allen Seiten abgesicherter
>> Ringbuffer.
>
> Der aber deutlich übersichtlicher, kürzer und schneller wäre.

Übersichtlichkeit ? Ich finde das sehr übersichtlich, ich mag Pointer
Kürzer und Schneller ?
Mhhh Interessant.. wie denn ? erleuchte mich doch bitte.

von Marc (gierig) Benutzerseite


Lesenswert?

Fall erledigt. Kann geschlossen und vergessen werden...

Karl Heinz allererste Annahme war richtig.

Im meinen Fall ein Pointer auf ein Array das STRUCT Referenzen enthält.
ein zugriff erfolgte ohne konkrete Zuweisung des Pointers.

danke für die Denkanstöße..

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.