PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [c] Pointer-Problem mit Liste


Gast
2006-05-23, 13:04:51
Hi!

Ich habe ein Problem mit meiner selbstgestrickten Liste 'serviceDesc'. 'serviceDescList' ist der Anker der Liste.
Ein dienstanbietender Server soll sich bei einem Broker (siehe Code unten) registrieren. Diese Informationen sollen in der Liste gespeichert werden (siehe IF unten).
Die Funktion 'listAdd' wird aufgerufen und man gelangt in den IF-Zweig, weil 'serviceDescList' noch NULL ist (leere Liste).
Vorher wurde ein neues Element angelegt und mit Werten versehen. Nun soll der Anker auf dieses neue Element zeigen.

Ich erwartete nun, dass ich per Anker auf das erste Element zugreifen kann und etwas, zB den String 'service', per printf ausgeben kann (siehe ganz unten <-- ??).
Es wird aber (null) ausgegeben!

Innerhalb der Funktion kann ich' sd->service' aber korrekt ausgeben lassen.
'serviceDescList->service' liefert aber vorher und nachher (siehe unten <-- vorher/nachher) ebenfalls (null).

Und ich weiss leider nicht, woran das liegt...

Wäre nett, wenn mir jemand helfen könnte. :)


typedef struct _serviceDesc {
char service[20];
char ip[20];
int port;
struct _serviceDesc *next;
} serviceDesc;


void listAdd(serviceDesc *serviceDescList, char* service, char* ip, int port) {
serviceDesc *sd = (serviceDesc *)malloc(sizeof(serviceDesc));
strcpy(sd->service,service);
strcpy(sd->ip,ip);
sd->port = port;
sd->next = NULL;
if (serviceDescList == NULL) {
serviceDescList = sd; // <-- vorher/nachher printf
} else {
serviceDesc *help = serviceDescList; // help zeigt auf Anfang
for ( ; help->next != NULL; help = help->next ) ; // help zeigt nun auf Ende
help->next = sd;
}
}//end listAdd


int main() {
serviceDesc *serviceDescList = NULL; // Listen-Anker
...
if ( strcmp(query,"REGISTER") == 0 ) {
printf("Broker: Anfrage erhalten: \"%s %s %d (von %s)\"\n",
query, remoteServiceName, remotePort,remoteIP);
listAdd(serviceDescList, remoteServiceName, remoteIP, remotePort);
}
printf("%s\n", serviceDescList->service); // <---- ??
...
}

Neomi
2006-05-23, 14:08:53
Du übergibst den Pointer auf den Anker als lokalen Parameter, der wird dann lokal überschrieben und bleibt außerhalb der Funktion NULL. Es gibt in etwa diese Lösungen:

a) den Anker global definieren (bäh)
b) eine Referenz oder einen Pointer auf den Pointer übergeben
c) die Liste kapseln (sauberste Lösung)

Variante b) sähe so aus:

typedef struct _serviceDesc {
char service[20];
char ip[20];
int port;
struct _serviceDesc *next;
} serviceDesc;


void listAdd(serviceDesc **serviceDescList, char* service, char* ip, int port) {
serviceDesc *sd = (serviceDesc *)malloc(sizeof(serviceDesc));
strcpy(sd->service,service);
strcpy(sd->ip,ip);
sd->port = port;
sd->next = NULL;
if (*serviceDescList == NULL) {
*serviceDescList = sd; // <-- vorher/nachher printf
} else {
serviceDesc *help = *serviceDescList; // help zeigt auf Anfang
for ( ; help->next != NULL; help = help->next ) ; // help zeigt nun auf Ende
help->next = sd;
}
}//end listAdd


int main() {
serviceDesc *serviceDescList = NULL; // Listen-Anker
...
if ( strcmp(query,"REGISTER") == 0 ) {
printf("Broker: Anfrage erhalten: \"%s %s %d (von %s)\"\n",
query, remoteServiceName, remotePort,remoteIP);
listAdd(&serviceDescList, remoteServiceName, remoteIP, remotePort);
}
printf("%s\n", serviceDescList->service); // <---- ??
...
}

Gast
2006-05-23, 15:29:26
Kann ich nicht nachvollziehen (auch wenns wohl funktioniert).
Im Funktionsaufruf übergebe ich doch schon einen Zeiger.
Die Adresse des Zeigers übergeben?! Sachen gibts, die sollte es nicht geben...

Aber danke, ich werds mal probieren. ;)

Coda
2006-05-23, 16:04:07
void foo(int lala)
{
lala = 10;
}

int main()
{
int lala = 0;
foo(lala);
printf("%d\n",lala);
}Ausgabe: 0
Genau das ist dein Problem. Ob das jetzt ein int oder ein Pointer ist, spielt dabei keine Rolle.

del_4901
2006-05-23, 17:55:13
Gast[/POST]']Kann ich nicht nachvollziehen (auch wenns wohl funktioniert).
Im Funktionsaufruf übergebe ich doch schon einen Zeiger.
Die Adresse des Zeigers übergeben?! Sachen gibts, die sollte es nicht geben...

Aber danke, ich werds mal probieren. ;)

Klar Zeiger auf Zeiger sind sehr beliebt (ich mach das gern)
Ein Array ist doch auch blos ein Zeiger!
Und ein Array von Zeigern ist halt ein Zeiger auf Zeiger. ^^

Bei deinem Problem könntest du auch eine Referenzübergabe machen (einfach vor die zu ändernden Funktionsparameter ein & schreiben)
Leztenendes macht der Compiler dann auch nur das draus was Neomi gepostet hat ... es sieht nur schoener aus, und ist Anfängerfreundlicher.
Ist halt syntaktischer Zucker ^^