Call-by-Reference Problem
-
Hallo, ich habe wohl ein Verständnisproblem beim Call-By-Reference-Konzept mit Strukturen. Hier ein (vereinfachtes) Codebeispiel:
#include <stdio.h> typedef struct someStruct *POINTER; struct someStruct { int number; }; void test(POINTER p_test) { struct someStruct lv_test; lv_test.number = 4711; p_test=&lv_test; printf("\nNumber internal:%d\n", p_test->number); } int main () { struct someStruct s; s.number=815; test(&s); printf("\nNumber external:%d\n", s.number); while(1); }
Der Output bei "Number external" ist wieder 815. Anscheined wird also trotz übergabe der Rerenz mit test(&s); in der Methode test mit einer Kopie gerarbeitet.
Ich vermute die Lösung ist sehr simpel und ich sehe den Wald gerade vor lauter Bäumen nicht
-
So ist es.
Du hast dir die Antwort selbst gegeben.
In C gibt es kein call by reference, es gibt hier ausschließlich call by value, d.h. es wird immer kopiert.
-
Hallo,
bist du dir da sicher? Wenn ich "C Call by Reference" google bekomme ich massenweise Ergebnisse.
Im grunde geht es mir darum einen bestehenden Pointer einer Methode zu übergeben, die dann diesen Pointer auf ein andere Struktur zeigen lässt. Dies soll dann auch in der aufrufenden Methode erkennbar sein.
-
Was Du vermutlich möchtest, ist:
void test(POINTER p_test) { p_test->number = 4711; printf("\nNumber internal:%d\n", p_test->number); }
Wenn Dein Pointer nach Funktionsaufruf woanders hin zeigen soll, musst Du der Funktion die Adresse des Pointers übergeben.
Außderdem musst Du dann auch dafür sorgen, dass das, wohin der Pointer anschließend zeigen soll, auch nach Funktionsende noch existiert. Das ist in Deinem Ausgangsbeispiel nicht der Fall!
-
Hallo Belli,
was Du machen wolltest ist wohl:
void test(POINTER p_test) {
struct someStruct *lv_test;
lv_test = p_test;
lv_test->number = 4711;
printf("\nNumber internal:%d\n", p_test->number);}
Nun zeigen Lv_test und p_test auf den gleichen Speicherbereich und die Variable in p_test wird verändert.
-
Basti91 schrieb:
Im grunde geht es mir darum einen bestehenden Pointer einer Methode zu übergeben, die dann diesen Pointer auf ein andere Struktur zeigen lässt. Dies soll dann auch in der aufrufenden Methode erkennbar sein.
Momentan kopierst Du den Zeiger (und übergibst die Struktur "per Referenz").
Wenn Du den Originalzeiger verbiegen willst, musst Du der Pointer "per Referenz" übergeben.void test(POINTER *p_test);
-
Hallo, die Adresse des Pointers übergebe ich doch mit dem Adressoperator-& beim Funktionsaufruf.
Das Beispiel ist in Wirklichkeit etwas komplexer. Es handelt sich um einen binären Suchbaum. in der Funktion test "hangelt" man sich von der globalen Variable root ausgehend, zu dem Objekt mit der übergebenen ID (zweiter Parameter, in diesem Beispiel nicht gegeben) und speichert die Adresse des gefundenen Records im übergebenen Pointer.
In der aufrufenden Funktion soll dann, nachdem der Record gefunden wurde, dieser über diesen Pointer weiter bearbeitet werden.
-
Basti91 schrieb:
Hallo, die Adresse des Pointers übergebe ich doch mit dem Adressoperator-& beim Funktionsaufruf.
Nö. In Deinem Beispiel ist s (in main) eine Struktur und &s (bei dem Funktionsaufruf) die Adresse der Struktur.
@Bonni435:
Nö. Warum sollte ich den Umweg über einen extra deklarierten Zeiger machen wollen?
-
Könntet Ihr vielleicht eure Ideen analog meinem Beispiel in etwas mehr Code formulieren. Leider helfen mir einzelne Snippets nicht weiter.
-
Ungetestet:
#include <stdio.h> typedef struct someStruct *POINTER; struct someStruct { int number; }; /* Damit die Strukturen nicht via malloc/free angeschafft werden müssen, für dieses Beispiel ausnahmsweise mal global: */ struct someStruct eins; struct someStruct zwei; void test(POINTER *p_test/*Pointer auf Pointer auf someStruct*/) { *p_test=&zwei; printf("\nNumber internal:%d\n", (*p_test)->number); } int main () { POINTER structPointer = &eins; eins.number = 1; zwei.number = 2; test(&structPointer); printf("\nNumber external:%d\n", structPointer->number); while(1); }
-
Kannst du deinen eigenen Text nicht lesen?
in der Methode test mit einer Kopie gerarbeitet.
D.h. du arbeitest in der Funktion immer auf einer Kopie (ob das Argument nun selbst ein Zeiger ist oder nicht, ist uninteressant, begreifen aber >95% der Laien und Tutorialschreiber nicht).
-
Belli schrieb:
@Bonni435:
Nö. Warum sollte ich den Umweg über einen extra deklarierten Zeiger machen wollen?
Hallo Belli,
im Prinzip schreibe ich das gleiche wie Du. Ich habe nur den Code vom TE angepasst. Natürlich ist die lokale Variable nicht erforderlich.
-
Bonni435 schrieb:
Hallo Belli,
im Prinzip schreibe ich das gleiche wie Du.Spitze! Daumen hoch!