|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
Problema con i puntatori di C
Ragazzi, con sti puntatori sto diventando scemo!
Pensavo di avere capito bene la questione ma a quanto pare non è così! Vi prego di rispondere alla mia domanda perchè davvero non so più che fare!!! Se io ho: Codice:
struct sockaddr_in server; Codice:
(struct sockaddr*)&server Ma se io faccio così: Codice:
struct sockaddr_in *server; Codice:
(struct sockaddr*)server Nel primo caso faccio un cast sull'indirizzo dellla struttura server e nel secondo lo faccio sul contenuto del puntatore alla struttura che è acora l'indirizzo della struttura server! Vi prego ditemi cosa mi sfugge perchè il mio compilatore non la pensa come me!!! ...e io non so più a che santo rivolgermi!!! ![]() Ultima modifica di Swalke : 13-07-2008 alle 14:26. |
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Re: Problema con i puntatori di C
Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
Si, ma io la struttura puntata da *server l'ho inizializzata e poi assegnata a al puntatore *server!
...non ho postato l'assegnazione e l'inizializzazione per snellire il messaggio! Ultima modifica di Swalke : 13-07-2008 alle 14:27. |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#5 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
...ilsensine. forse il problema è quello che dici tu ma io ho le idee un po' confuse e non capisco alcune cose!
Ti posto i codici dei programmi... ...ho cercato di ridurli all'osso e di commentarli a dovere... ...ma da quello che mi è parso tu ne capisci molto e non avrai difficoltà! Faccio prima alcune premesse per farti perdere meno tempo possibile: Nel primo post avevo rappresentato il cast su una variabile e un puntatore server. OKKIO che nel programma che ti posto la stessa cosa è fatta su una variabile client... ...lo dico per non che ti si confondano le idee sulla mia domanda! Il problema è che ho due programmi, un client e un server. Il server si mette in ascolto, il client lo contatta e il server gli scrive un messaggio, tutto qui. Ti posto tre codici: IL 1° è il codice del server funzionante IL 2° è il codice del server non funzionante. Le uniche differenze dal 1° stanno nella riga 18 dove server è un puntatore, nella 56 dove mi cambia il cast e nalla 67 (ma questa è in influente) IL 3° è il client. Questo è giusto e l'ho messo solo perchè così vedi cosa avviene! OKKIO che tutti i codici vengono compilati correttamente, l'errore lo hai in esecuzione! Se usi il server corretto tutto funge, invece se usi il server sbagliato, quando fai partire il client, questo sttampa un messaggio ricevuto dal server che è una serie di caratteri sballati, poi termina e uccide il server!!! Ultime 2 cose: ricordati di passare "localhost" quando fai partire il client e ricordati di fare una kill sul server corretto quando hai finito perchè resta in esecuzione!!! Eccoti i codici: SERVER FUNZIONANTE: Codice:
#include <unistd.h> #include <stdio.h> /*per potere utilizzare la printf*/ #include <errno.h> /*contiene la definizione dei nomi simbolici dei codici di errore*/ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> /* netbd.h è necessario per struct hostent e herror */ #define PORT 3550 /* porta che verrà aperta */ #define BACKLOG 2 /* numero di connessioni permesse */ int main() { int controller; //conterrà l'esito di una chiamata a funzione struct sockaddr_in server; struct sockaddr_in client; int addrlen; //(ci servirà nella funzione "accept") int fd; //descrittore della socket del server int fd2; //descrittore della socket impegnata con un client fd=socket(AF_INET, SOCK_STREAM, 0); //inizializzo una socket di tipo SOCK_STREAM bzero(&server, sizeof(server)); //inizializza a 0 la struttura server //popoliamo i campi della struttura sockaddr_in "server" server.sin_family=AF_INET; //setto il protocolllo usato server.sin_port=htons(PORT); //setto il numero di porta server.sin_addr.s_addr=INADDR_ANY; //setto l'ip della macchina. //INADDR_ANY da automaticamente l'indirizzo ip dell'host locale. controller=bind(fd, (struct sockaddr *)&server, sizeof(server)); //server è una struttura sockaddr_in mentre "bind" accetta //come secondo parametro un puntatore a una struttura sockaddr //ecco il perchè de cast if(controller==-1) { perror("Errore in Bind"); exit(255); } controller=listen(fd, BACKLOG); //il server si mette in attesa di chiamate if(controller==-1) { perror("Errore in Listen"); exit(255); } printf("SERVER - Accetto delle richieste di connessione alla porta %d\n", PORT); while(1) //ciclo infinito { addrlen=(sizeof(struct sockaddr_in)); fd2=accept(fd, (struct sockaddr *)&client, &addrlen); //seleziona una richiesta di un client //client è una struttura sockaddr_in mentre "accept" accetta //come parametro un puntatore a una struttura sockaddr //ecco il perchè de cast if (fd2 == -1) { perror("Errore in Accept"); exit(255); } printf("SERVER - Connessione da parte di: %s\n", inet_ntoa(client.sin_addr)); //Con il Casting converto il puntatore al CAMPO sin_addr in un puntatore alla struttura in_addr controller=write(fd2, "Benvenuto sul mio server.\n", 25); //scriviamo un messaggio al client fd2 if (controller == -1) { perror("Errore in Write"); exit(-1); } close (fd2); } exit(0); } Codice:
#include <unistd.h> #include <stdio.h> /*per potere utilizzare la printf*/ #include <errno.h> /*contiene la definizione dei nomi simbolici dei codici di errore*/ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> /* netbd.h è necessario per struct hostent e herror */ #define PORT 3550 /* porta che verrà aperta */ #define BACKLOG 2 /* numero di connessioni permesse */ int main() { int controller; //conterrà l'esito di una chiamata a funzione struct sockaddr_in server; struct sockaddr_in *client; int addrlen; //(ci servirà nella funzione "accept") int fd; //descrittore della socket del server int fd2; //descrittore della socket impegnata con un client fd=socket(AF_INET, SOCK_STREAM, 0); //inizializzo una socket di tipo SOCK_STREAM bzero(&server, sizeof(server)); //inizializza a 0 la struttura server //popoliamo i campi della struttura sockaddr_in "server" server.sin_family=AF_INET; //setto il protocolllo usato server.sin_port=htons(PORT); //setto il numero di porta server.sin_addr.s_addr=INADDR_ANY; //setto l'ip della macchina. //INADDR_ANY da automaticamente l'indirizzo ip dell'host locale. controller=bind(fd, (struct sockaddr *)&server, sizeof(server)); //server è una struttura sockaddr_in mentre "bind" accetta //come secondo parametro un puntatore a una struttura sockaddr //ecco il perchè de cast if(controller==-1) { perror("Errore in Bind"); exit(255); } controller=listen(fd, BACKLOG); //il server si mette in attesa di chiamate if(controller==-1) { perror("Errore in Listen"); exit(255); } printf("SERVER - Accetto delle richieste di connessione alla porta %d\n", PORT); while(1) //ciclo infinito { addrlen=(sizeof(struct sockaddr_in)); fd2=accept(fd, (struct sockaddr *)client, &addrlen); //seleziona una richiesta di un client //client è una struttura sockaddr_in mentre "accept" accetta //come parametro un puntatore a una struttura sockaddr //ecco il perchè de cast if (fd2 == -1) { perror("Errore in Accept"); exit(255); } printf("SERVER - Connessione da parte di: %s\n", inet_ntoa(*(struct in_addr *) client->sin_addr.s_addr)); //Con il Casting converto il puntatore al CAMPO sin_addr in un puntatore alla struttura in_addr controller=write(fd2, "Benvenuto sul mio server.\n", 25); //scriviamo un messaggio al client fd2 if (controller == -1) { perror("Errore in Write"); exit(-1); } close (fd2); } exit(0); } Codice:
#include <unistd.h> #include <stdio.h> /*per potere utilizzare la printf*/ #include <errno.h> /*contiene la definizione dei nomi simbolici dei codici di errore*/ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> /* netbd.h è necessario per struct hostent e herror */ #define PORT 3550 /* porta che verrà aperta */ #define BACKLOG 2 /* numero di connessioni permesse */ int main(int argc, char *argv[]) { int controller; //conterrà l'esito di una chiamata a funzione struct hostent *myhost; struct sockaddr_in server; //conterrà le info relative alla socket server int fd; //descrittore della socket del server int fd2; //descrittore della socket impegnata con un client char buf[100]; if(argc != 2) { printf("Non è stato passato un ip al lancio del programma!\n"); exit(255); } myhost=gethostbyname(argv[1]); //gethostbyname ritorna un puntatore! if(myhost==NULL) { herror("Errore nella gethostbyname"); exit(255); } fd=socket(AF_INET, SOCK_STREAM, 0); //inizializzo una socket di tipo SOCK_STREAM bzero(&server, sizeof(server)); //inizializza a 0 la struttura server server.sin_family=AF_INET; //setto il protocolllo usato server.sin_port=htons(PORT); //setto il numero di porta server.sin_addr=*((struct in_addr *)myhost->h_addr); //setto l'ip della macchina. printf("CLIENT - Mi connetto alla porta %d di %s!\n", PORT, argv[1]); controller=connect(fd, (struct sockaddr*)&server, sizeof(struct sockaddr)); if(controller==-1) { perror("Errore in Connect"); exit(255); } controller=read(fd, buf, 26); //scriviamo un messaggio al client fd2 if (controller == -1) { perror("Errore in Read"); exit(-1); } buf[26]='\0'; printf("CLIENT - Messaggio del server: %s\n", buf); close(fd); /* chiude fd */ printf("CLIENT - Fine\n"); exit(0); } Forse è proprio come dicevi tu, ma non capisco il perchè! La funzione accept dovrebbe inizializzare la struttura puntata da *client no? Allora perchè il cast del server non funzionante non va bene!!!?? Ultima modifica di Swalke : 13-07-2008 alle 14:27. |
![]() |
![]() |
![]() |
#6 | ||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
||
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#8 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
Scusa ma ancora ne capisco un po' poco!
...ma allora dimm un po... Il cast di un puntatore non lo puoi mai fare se hai creato un puntatore che ancora non punta a nulla? Non capisco perchè! ...con il cast di un puntatore come nel mio caso non stai semplicemente dicendo: trasforma il mio puntatore da un punataore al tipo x a un puntatore al tipo y? ![]() ...uff Ultima modifica di Swalke : 13-07-2008 alle 14:28. |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Per farti capire a cosa serve un puntatore, partiamo dall'esempio non funzionante e aggiungi queste dichiarazioni all'inizio di main: Codice:
struct sockaddr_in client_1; struct sockaddr_in client_2; client = &client_1; la accept "riempirà" la struttura client_1. Se invece metti client = &client_2; la accept "riempirà" client_2. Domanda: se non metti nulla dentro "client" (quindi lo lasci "non inizializzato", o meglio "inizializzato a casaccio" ![]() ![]()
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#10 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
Ora ho capito!!!
Il tuo esempio è stato perfetto!!! La risposta lla tua domanda non è semplice però! Dove scrive la bind se ancora il puntatore non punta a nulla? ...di sicuro da qualche parte scrive perchè non m iritorna un -1! ...o sbaglio? Inoltre come mai il compilatore non si accorge di un errore del genere? ...poi ho anche un'altra domandina ma la lascio per dopo... SEI UN MITO!!! Ultima modifica di Swalke : 13-07-2008 alle 14:29. |
![]() |
![]() |
![]() |
#11 | ||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Scrive nella locazione di memoria puntata dal puntatore. Se non ti ritorna errore e il programma non ti è andato in crash, stai sicuro di aver corrotto qualche parte della memoria del tuo programma. Quote:
![]() (*) Garbage In, Garbage Out
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
||
![]() |
![]() |
![]() |
#12 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
TUTTO OK!!!
Quella del GIGO mela sono segnata!!! ...e l'altra domanda non serve più!!! Grazie mille ilsensine!!! Il forum con te diventa praticamente un chat!!! ![]() ...se mi vengono altri dubbi su sto programma mi faccio risentire!!! Ultima modifica di Swalke : 13-07-2008 alle 14:29. |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Jul 2000
Città: Vignola (MO)
Messaggi: 316
|
Grazie ilsensine ho capitoa anche io.... sei stao mooolto utile...
Ciao
__________________
<Asus A8N-E Deluxe> <Amd64 3000+> <Ram 2.5 Gb> <Geffo3> <2 Maxtor 160 Gb RAID 1> <Adsl ZyXEL 645r> <ESS Maestro> <GNU/Linux Debian Etch> ![]() Wii 1037 4238 6261 1967 |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 09:21.