Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Dubbio sul ritorno della funzione
Forum - C/C++ - Dubbio sul ritorno della funzione

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
Driverfury (Normal User)
Rookie


Messaggi: 45
Iscritto: 21/09/2011

Segnala al moderatore
Postato alle 14:36
Lunedì, 19/12/2011
Ciao a tutti, stavo creando una rubrica in C quando andando a compilare in una funzione c'è stato l'errore: "incompatible types in return". Ecco il file sorgente:

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. // Variabili e costanti globali
  6. const int MAX_CON = 500; // Costante che sta ad indicare il massimo numero di contatti della rubrica
  7.  
  8. // Struttura: Contatto
  9. struct contact
  10. {
  11.     char *name;
  12.     char *surname;
  13.     char *number;
  14.     char *address;
  15. };
  16.  
  17. // Prototipi di funzioni
  18. struct contact returnContacts(char *fileName);
  19.  
  20. int main()
  21. {
  22.     char *fname = "rubrica.txt"
  23.     struct contact c[MAX_CON];
  24.     c = returnContacts(fname);
  25. }
  26.  
  27. // Funzione che ritorna una struttura di contatti o un array di contatti
  28. struct contact returnContacts(char *fileName)
  29. {
  30.     FILE *fp; // Puntatore a file
  31.     struct contact c[MAX_CON]; // Variabile di tipo struttura "contact"
  32.     int i=0; // Contatore
  33.    
  34.     if(!(fp=fopen(fileName, "r"))) // Se non riesce ad aprire il file in modalità di scrittura
  35.     {
  36.         printf("\nErrore durante l'apertura del file \"%s\" in modalita' lettura.\n", fileName);
  37.         return;
  38.     }
  39.    
  40.     while(fscanf(fp, "%s %s %s %s\n", c[i].name, c[i].surname, c[i].number, c[i].address)>0) /* Fin quando
  41.     riesce a leggere da file più di 0 Byte */
  42.     {
  43.         i++;
  44.     }
  45.    
  46.     fclose(fp); // Chiudo il file
  47.  
  48.  
  49.     return c; // Questo è l'errore!!!
  50. }



L'errore c'è quando ritorno "c" dalla funzione returnContacts(). Mi potete aiutare a farmi perchè c'è l'errore?

PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2763
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 14:43
Lunedì, 19/12/2011

allora, a parte l'errore sintattico sulla dichiarazione della funzione che dovrebbe essere "struct contact *", c'è un gravissimo errore semantico che non farà funzionare nulla e sono sicuro che non ci sbatteresti la testa per giorni.

non si può ritornare un array statico da una funzione, il motivo è che l'area di memoria dove è allocato va fuori scopo dopo il ritorno della funzione. per risolvere il problema ci sono due strade, la prima è allocare l'array con malloc, ovvero far si che risieda nell'heap e non nello stack. il contro di questa opzione è che ti devi ricordare di chiamare free sull'array dopo che hai utilizzato i dati nel main, altrimenti ti ritroverai con un memory leak.

la seconda strada, quella che io consiglio, è passare l'array di output come parametro della funzione e riempirlo all'interno della stessa. in questo modo la funzione non si deve occupare dell'allocazione della memoria ma è gestito tutto dal main.


Ingegnere Informatico
https://ldlagency.it
PM Quote
Avatar
Driverfury (Normal User)
Rookie


Messaggi: 45
Iscritto: 21/09/2011

Segnala al moderatore
Postato alle 16:33
Lunedì, 19/12/2011
Innanzitutto grazie. Ho provato a modificare il codice secondo i tuoi consigli:

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. // Variabili e costanti globali
  6. const int MAX_CON = 500; // Costante che sta ad indicare il massimo numero di contatti della rubrica
  7.  
  8. // Struttura: Contatto
  9. struct contact
  10. {
  11.     char *name;
  12.     char *surname;
  13.     char *number;
  14.     char *address;
  15. };
  16.  
  17. // Prototipi di funzioni
  18. struct contact * returnContacts(char *fileName, struct contact c[MAX_CON]);
  19.  
  20. int main()
  21. {
  22.     char *fname = "rubrica.txt"
  23.     struct contact c[MAX_CON];
  24.     c = returnContacts(fname, c);
  25. }
  26.  
  27. // Funzione che ritorna un array di contatti
  28. struct contact * returnContacts(char *fileName, struct contact c[MAX_CON])
  29. {
  30.     FILE *fp; // Puntatore a file
  31.     int i=0; // Contatore
  32.    
  33.     if(!(fp=fopen(fileName, "r"))) // Se non riesce ad aprire il file in modalità di scrittura
  34.     {
  35.         printf("\nErrore durante l'apertura del file \"%s\" in modalita' lettura.\n", fileName);
  36.         return;
  37.     }
  38.    
  39.     while(fscanf(fp, "%s %s %s %s\n", c[i].name, c[i].surname, c[i].number, c[i].address)>0) /* Fin quando
  40.     riesce a leggere da file più di 0 Byte */
  41.     {
  42.         i++;
  43.     }
  44.    
  45.     fclose(fp); // Chiudo il file
  46.     return c; // Ritorna il contatto o l'array di contatti
  47. }



... Purtroppo l'errore è lo stesso... potresti aiutarmi più nel dettaglio?

Ultima modifica effettuata da Driverfury il 19/12/2011 alle 16:34
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5460
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 16:42
Lunedì, 19/12/2011
Non hai proprio seguito tutti i consigli ... la funzione NON deve restituire nulla dato che lavora con il vettore passato come parametro.

Quindi sarà di tipo

void

e non

struct contact *

la chiamerai con

returnContacts(fname, c);

e non ci sarà la riga

return c;

P.S. In merito alla tua firma, qual è la Domanda ?


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
Bonny (Member)
Expert


Messaggi: 435
Iscritto: 24/04/2009

Segnala al moderatore
Postato alle 16:44
Lunedì, 19/12/2011
non poi passare il vettore con la sua dimensione come parametro di una funzione....
Codice sorgente - presumibilmente C/C++

  1. struct contact * returnContacts(char *fileName, struct contact c[MAX_CON]);



devi farlo cosi
Codice sorgente - presumibilmente C++

  1. struct contact * returnContacts(char *fileName, struct contact c[]);
  2. //or
  3. struct contact * returnContacts(char *fileName, struct contact *c);


il vettore viene passato per riferimento... ovvero viene passato il puntatore alla prima allocazione di memoria  del vettore
adesso capisci perchè Hedo ti ha consigliato di passarlo come parametro?
tutte le operazioni (assegnamento ecc..) che fai sul vettore, al termine della funzione restano "persistenti" in esso segue che non serve fare il return, quindi diventa:
Codice sorgente - presumibilmente C/C++

  1. void returnContacts(char *fileName, struct contact c[]);



Ultima modifica effettuata da Bonny il 19/12/2011 alle 16:49


Bonny
PM Quote
Avatar
Driverfury (Normal User)
Rookie


Messaggi: 45
Iscritto: 21/09/2011

Segnala al moderatore
Postato alle 18:43
Lunedì, 19/12/2011
Testo quotato

Postato originariamente da nessuno:

Non hai proprio seguito tutti i consigli ... la funzione NON deve restituire nulla dato che lavora con il vettore passato come parametro.

Quindi sarà di tipo

void

e non

struct contact *

la chiamerai con

returnContacts(fname, c);

e non ci sarà la riga

return c;

P.S. In merito alla tua firma, qual è la Domanda ?  



Sì, è vero avevo interpretato male quanto citato da Hedo. Grazie mille nessuno, sei sempre molto disponibile e pronto ad aiutare. :k:

Ultima modifica effettuata da Driverfury il 29/08/2015 alle 1:51
PM Quote
Avatar
Driverfury (Normal User)
Rookie


Messaggi: 45
Iscritto: 21/09/2011

Segnala al moderatore
Postato alle 18:56
Lunedì, 19/12/2011
Comunque ho modificato il codice come mi avete consigliato ma l'applicazione si blocca e si chiude. Premetto che il file "rubrica.txt" esiste. Ecco come ho modificato il codice:

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. // Variabili e costanti globali
  6. const int MAX_CON = 500; // Costante che sta ad indicare il massimo numero di contatti della rubrica
  7.  
  8. // Struttura: Contatto
  9. struct contact
  10. {
  11.     char *name;
  12.     char *surname;
  13.     char *number;
  14.     char *address;
  15. };
  16.  
  17. // Prototipi di funzioni
  18. void returnContacts(char *fileName, struct contact c[]);
  19.  
  20. int main()
  21. {
  22.     char *fname = "rubrica.txt"
  23.     struct contact c[MAX_CON];
  24.     returnContacts(fname, c);
  25. }
  26.  
  27. // Procedura che assegna un array di contatti
  28. void returnContacts(char *fileName, struct contact c[])
  29. {
  30.     FILE *fp; // Puntatore a file
  31.     int i=0; // Contatore
  32.    
  33.     if(!(fp=fopen(fileName, "r"))) // Se non riesce ad aprire il file in modalità di scrittura
  34.     {
  35.         printf("\nErrore durante l'apertura del file \"%s\" in modalita' lettura.\n", fileName);
  36.         return;
  37.     }
  38.    
  39.     while(fscanf(fp, "%s %s %s %s\n", c[i].name, c[i].surname, c[i].number, c[i].address)>0) /* Fin quando
  40.     riesce a leggere da file più di 0 Byte */
  41.     {
  42.         i++;
  43.     }
  44.    
  45.     fclose(fp); // Chiudo il file
  46. }


PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5460
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 19:12
Lunedì, 19/12/2011
Testo quotato

Postato originariamente da Driverfury:

Comunque ho modificato il codice come mi avete consigliato ma l'applicazione si blocca e si chiude.



Per il futuro, il fatto che un'applicazione venga corretta (e vengano eliminati gli errori di compilazione) non significa che funzioni quando venga eseguita e non ci possano essere "altri" errori (a runtime appunto).

Il problema del tuo codice è causato dal fatto che hai utilizzato, nella struttura, dei puntatori a char e li hai utilizzati direttamente "senza allocare lo spazio" per ogni stringa. Questo causa (almeno) un crash dell'applicazione (come capita a te).

P.S. Per la firma, ok ... de gustibus ...


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1787
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 20:14
Lunedì, 19/12/2011
per dovere di cronaca, in C le funzioni possono ritornare anche intere struct, non per forza puntatori ad esse. In tal caso il compilatore infila un memcpy a tradimento, risolvendo tra l'altro il problema di allocazione della memoria per una singola struct (che introduce overhead e frammentazione dell'heap).

Questa era una limitazione Pre-ANSI ISO C89, mi sorprende che qualcuno se ne ricordi ancora O_o''

Io avevo 3 anni quando hanno sistemato questo problema :rofl:

Ultima modifica effettuata da TheKaneB il 19/12/2011 alle 20:17


Software Failure: Guru Meditation
Forum su Informatica, Elettronica, Robotica e Tecnologia: http://www.nonsoloamiga.com
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo