Forum: Mikrocontroller und Digitale Elektronik Zeiger - Knoten im Kopf?


von Tom G. (Gast)


Lesenswert?

Hallo!

Folgende Situation in C:

Es ist in einem fertigen Code ein array aus structs definiert.
Diesen Code möchte ich nicht ändern (zu viel aufwand)
1
const structa *structarray [] =
2
{
3
 &structelementa,
4
 &structelementb,
5
 ...,
6
};

Nun möchte ich dieses structarray an eine Function übergeben. Streng 
genommen  also den Zeiger.

Wie mache ich das?
So klappts ned.
1
void func (structa *uebergebenesstruct)
2
{
3
  irgendwastun();
4
}
5
6
func(&structarray); //Compiler meldet zwar keinen Fehler funktioniert aber nicht
Ich würde mich sehr über eine Erklärung freuen.
Vielen Dank

von _ebtschi_ (Gast)


Lesenswert?

In der Funktion musst du die Variable als 
uebergebenesstruct[i].irgendwas ansprechen. Also mit Stern davor. Keine 
Ahnung ob du das beachtet hast, wäre aber mein erster Tipp.

Ah, übersehen: das & gehört wohl weg, die Variable structarray ist 
bereits ein Pointer, und du willst ja nicht die Adresse von dem Pointer 
übergeben, nehm ich zumindest mal an ;-)

von Name (Gast)


Lesenswert?

Wenn du eine Zeiger auf ein Struct übergeben hast kannst du nicht mehr 
über uebergebenesstruct.structelement zugreifen, sondern must 
dereferenzieren,
also uebergebenesstruct->structelement oder 
(*uebergebenesstruct).structelement vlt. liegts daran

von Rolf Magnus (Gast)


Lesenswert?

> Es ist in einem fertigen Code ein array aus structs definiert.

Das ist ein Array aus Zeigern, nicht eines aus Structs.

> Nun möchte ich dieses structarray an eine Function übergeben. Streng
> genommen  also den Zeiger.

Kommt drauf an, was du mit "den Zeiger" meinst.

> Wie mache ich das?

Du mußt einen Zeiger auf das erste Element des Arrays übergeben. Dazu 
reicht es, den Namen des Arrays anzugeben. Daraus wird bei der 
Parameterübergabe automatisch ein Zeiger auf das erste Element.

> So klappts ned.
> void func (structa *uebergebenesstruct)

Du hast ja auch ein Array aus Zeigern auf structa. Ein Zeiger auf ein 
Element dieses Array wäre vom Typ Zeiger auf Zeiger auf structa, also 
müßte es heißen:
1
void func (structa **uebergebenesstruct)

> func(&structarray); //Compiler meldet zwar keinen Fehler funktioniert
> aber nicht

Dann sind die Warnungen zu niedrig eingestellt. Der Typ stimmt nicht. 
Beim Funktionsparameter hast du eine Zeigerebene zu wenig, beim Aufruf 
eine zuviel. Also einfach:
1
func(structarray);

von Tom G. (Gast)


Lesenswert?

Hallo!

Vielen Dank erstmal.

Leider klappts noch nicht:

Der Compiler: pointer to different objects und zwar in der Zeile mit dem 
Funktionsaufruf:

func(structarray);

Tom G.

von Simon K. (simon) Benutzerseite


Lesenswert?

Versuche mal die Funktions-parameter-deklaration zu ändern:
1
void func (struct structa *uebergebenesstruct)
2
{
3
  irgendwastun();
4
}

von Karl H. (kbuchegg)


Lesenswert?

So muss es funktionieren
1
typedef struct structa_
2
{
3
  int a;
4
  int b;
5
} structa;
6
7
structa structelementa = { 0, 1 };
8
structa strcutelementb = { 2, 3 };
9
10
const structa *structarray [] =
11
{
12
 &structelementa,
13
 &structelementb,
14
};
15
16
void func (const structa **uebergebenesstruct)
17
{
18
  int i = uebergebenesstruct[0]->a;
19
  int j = uebergebenesstruct[0]->b;
20
21
  i = uebergebenesstruct[1]->a;
22
  j = uebergebenesstruct[1]->b;
23
}
24
25
int main()
26
{
27
  func( structarray );
28
}
Obwohl ich normalerweise nicht viel davon halte:
Man könnte die Funktionssignatur auch so anlegen, da wird
es eventuell etwas klarer:
1
void func (const structa *uebergebenesstruct[])
2
{
3
  ...

von Karl H. (kbuchegg)


Lesenswert?

ebtschi wrote:
> In der Funktion musst du die Variable als
> uebergebenesstruct[i].irgendwas ansprechen.

Äh. Nein.

> Ah, übersehen: das & gehört wohl weg, die Variable structarray ist
> bereits ein Pointer,

Sei mit solchen Aussagen vorsichtig.
Du magst vielleicht das richtige meinen, aber so wie es da steht
ist das erst mal grundfalsch. Die Variable structarray ist kein
Pointer sondern ein Array. Und ein Array ist nun mal kein
Pointer.

von Tom G. (Gast)


Lesenswert?

Mit dem Code von Karl heinz Buchegger erhalte ich keine Fehler.

Jedoch hab ich noch eine kleines Problem:
1
const structa *structarray [] =
2
{
3
 &structelementa,
4
 &structelementb,
5
 NULL
6
};
7
8
9
void func (const structa *uebergebenesstruct[])
10
{
11
 
12
 unsigned char count;
13
 
14
 while (&uebergebenesstruct[count] != NULL)          
15
 {
16
   count++;    
17
 }
18
}
Ich möchte hier prüfen wieviele Items in einem Array stehen. Dazu ist 
steht eine NULL am Ende des Arrays. Jetzt prüfe ich die Adressen im 
Array. So wie es oben im Code steht prüfe ich aber die Adresse des 
Zeigers auf die ArrayItems, oder? Welche Möglichkeiten habe ich direkt 
die Adresse der ArrayItems zu prüfen?

DANKE
Tom

von Tom G. (Gast)


Lesenswert?

Ich hab jetzt nochmal im Internet etwas gesucht. Aber irgendwie nichts 
gefunden. Gibts da überhaupt eine Möglichkeit?

Tom

von Tom G. (Gast)


Lesenswert?

Ich schonwieder!

@ Karl-Heinz Buchegger
Bei deinem Code bekomm ich einen Stackfehler. Irgendwas stimmt noch 
nicht.
Aber ich bin meinem Latein am Ende. Deshalb seit ihr gefragt :)!
Was mach ich bloß falsch?

Tom

von Ingo E. (ogni42)


Lesenswert?

count muss vor der Benutzung intialisiert werden:
1
unsigned char count = 0;

von Tom G. (Gast)


Lesenswert?

is klar, aber darin liegt nicht das Problem.

von Uhu U. (uhu)


Lesenswert?

In dieser Zeile ist der Fehler. Überleg mal, was du hier machst:

   while (&uebergebenesstruct[count] != NULL)

von Tom G. (Gast)


Lesenswert?

Steht im Text, dass das falsch ist. Da wird nämlich überprüft ob die 
Adresse Null ist. Ich möchte dagegen aber prüfen ob das letzte Element 
in dem einen Array Null ist.
Ich weiß nur nicht wie das gehen soll.

Tom

von Uhu U. (uhu)


Lesenswert?

Warum setzt du das & vor uebergebenesstruct[count]?

von der mechatroniker (Gast)


Lesenswert?

Preisfrage:

1. Was macht das & da?
2. was möchtest du machen?
3. Welches Zeichen solltest du aus deinem Code löschen?

von Tom G. (Gast)


Lesenswert?

:D Ja klar das "&".

Jetzt bleibt nur noch die Geschichte mit dem Stackoverflow.
Wenn ich die Warnstufe des Compilers hochsetze dann bekomme ich bei 
folgendem Funktionsaufruf einen Fehler (pointer to different objects)
1
func(structarray);

Vielen Dank
Tom

von Uhu U. (uhu)


Lesenswert?

Ohne den Code zu sehen, den du wirklich benutzt, kann ich leider keine 
Aussage machen.

Der Code aus Beitrag "Re: Zeiger - Knoten im Kopf?" erzeugt 
zumindest durch Rekursion keinen Stackoverflow, weil keine vorhanden 
ist.

Liegt es vielleicht am Prozessor? Daß der einfach nicht genug Speicher 
hat?

von Tom G. (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal die Auszüge aus dem Code

Tom

von Uhu U. (uhu)


Lesenswert?

Und du bist sicher, daß er in arrayedit abstürzt und nicht in ...?

Was ist das für ein Prozessor?

von Tom G. (Gast)


Lesenswert?

Der Compiler meldet einen Fehler bei

arrayedit (startframes);

Allerdings nur auf erhöhter Warnstufe.
Wenn ich "normal" compile, dann stürzt er bei

while (frame[count] != NULL)
{
    count++;
}

ab.

Prozessor ist ein CS167.

Tom

von Uhu U. (uhu)


Lesenswert?

Hast du einen Debugger? Wenn ja, geh das Programm mal im ASM-Modus 
durch, dann siehst du bei welchem Befehl es kracht.

An deinem Quelltext liegt es m.A. nicht. Vielleicht sind irgendwelche 
Compiler- oder Linkereinstellungen krumm...

Der Compilefehler dürfte keine Rolle spielen.

von Rolf Magnus (Gast)


Lesenswert?

> Der Compiler meldet einen Fehler

Welchen?

> Allerdings nur auf erhöhter Warnstufe.

Man sollte immer alle Warnungen an haben.

> Wenn ich "normal" compile, dann stürzt er bei
>
> while (frame[count] != NULL)
> {
>     count++;
> }
>
> ab.

Welchen Wert hat count beim Absturz?

von Tom G. (Gast)


Lesenswert?

Compiler: C166 Compiler V4.27 von Keil

Count hat den Wert 0 beim Absturz.

Tom

von Tom G. (Gast)


Lesenswert?

Ach ja der Fehler passiert bei ASM Befehl:

 0498E0:   D4 58 02 00  MOV       R5,[R8+#DPP0:0002H]

Tom

von Uhu U. (uhu)


Lesenswert?

Kannst du dir mal kurz bevor er abstürzt, mit dem Dumpfenster oder einer 
Dumpfunktion des Debuggers den Stack anzeigen lassen? Wieviel freier 
Stack ist vorhanden?

Hast du in den ASM-Modus geschaltet und das Programm mal Schritt für 
Schritt durchgegangen, bis es kracht?

Was ist das für ein Maschinenbefehl, der fehlschlägt?

von Rolf Magnus (Gast)


Lesenswert?

>>> Der Compiler meldet einen Fehler
>> Welchen?
> Compiler: C166 Compiler V4.27 von Keil

Ich meinte eher, welchen Fehler er meldet.

In deinem Code sehe ich keinen Fehler. Ich würde auch auf einen 
Stack-Overflow tippen, oder du hast dir irgendwo vorher durch einen 
fehlerhaften Pointer-Zugriff den Speicher zerschossen.

von Tom G. (Gast)


Lesenswert?

Der Compiler-Fehler:

*** WARNING C98 IN LINE 46 OF MD\FRAME.C: parameter 1: pointer to 
different objects
parameter 1: pointer to different objects

Das vorher ein Fehler ist kann ich ausschließen, da ich den Code auf das 
kleinst mögliche, spricht dem oben angegebenen Code, reduziert habe.

Ich habe das Programm vorher Schritt für Schritt durchlaufen lassen.
Wie gesagt der Fehler tritt bei diesem ASM Befehl auf.

0498E0:   D4 58 02 00  MOV       R5,[R8+#DPP0:0002H]

Betreffs des Maschinenbefehls und des Stacks muss ich mich erst in die 
Debuggerfunktionen einlesen.

von Karl H. (kbuchegg)


Lesenswert?

Tom G. wrote:

> Das vorher ein Fehler ist kann ich ausschließen, da ich den Code auf das
> kleinst mögliche, spricht dem oben angegebenen Code, reduziert habe.

Poste mal den kompletten Code. Obiges ist nicht kompilierbar.
Irgendetwas offensichtliches ist so nicht zu sehen und
die Fehlermeldung des Compilers ist auch nicht sehr aussage-
kräftig.

Schreib den Code nicht neu, sondern kopier ihn mittels Copy&Paste
hier herein. Da kannst auch dein originales File, das du zum
Testen benutzt, als Anhang anhängen.

von Tom G. (Gast)


Lesenswert?

Hallo!

Ich kann den Code leider nicht so veröffentlichen wie ich ihn benutze, 
das der  fertige Codeteil lizenzrechtlich geschützt ist. Wenn ich wieder 
die betreffenden Zeilen rauskopiere und umbennene bin ich wieder so weit 
wie vorher....
Manchmal ist es wirklich so, dass man den Wald vor lauter Bäumen nicht 
mehr sieht.

Ich versuche zu verstehen was der Compiler mit dieser "Warning" sagen 
will:
1
arrayedit (startframes);
Compiler: parameter 1: pointer to different objects

das mag er aber, da meckert er gar nicht:
1
arrayedit (&startframes);

Weiß jemand warum?

Tom

von Uhu U. (uhu)


Lesenswert?

Die Warnung ist irrelevant; nur ein Hinweis auf eine Unsitte, die früher 
in C legal und üblich war.

Wahrscheinlich verschwindet sie, wenn du arrayedit so definierst:

   void arrayedit(const xframes **frame)

un wird dir nichts anderes übrig bleiben, als dich in den Debugger 
einzuarbeiten und dich mit der Maschinenebene des Prozessors zu befassen 
- das hat aber noch keinem geschadet.

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.