[C] stringa=NULL dopo return funzione

di il
7 risposte

[C] stringa=NULL dopo return funzione

Ciao a tutti ho una funzione (make_connected_user_list) che crea una lista di nomi che mi crea qualche problema.
Più in dettaglio da un thread (frammento di codice sotto) dichiaro un puntatore ad una stringa e poi chiamo la funzione make_connected_user_list
char *s=NULL;
if((make_connected_user_list(s))!=0){
    fprintf(stderr,"Errore nella creazione della lista degli utenti connessi; Funzione worker\n");
    //setto il messaggio di errore da inviare al client
    setHeader(&msg->hdr, OP_FAIL, server);
    setData(&msg->data, "", NULL, 0);
    //aggiorno le statistiche:errori++
    if((update_stats(0,0,0,0,0,0,1,0,0))!=0)
	fprintf(stderr, "Errore nell'aggiornamento delle statistiche\n");
    failure++;
    }
    else{
	//aggiorno le statistiche:operazione lecite++
	if((update_stats(0,0,0,0,0,0,0,1,0))!=0)
		fprintf(stderr, "Errore nell'aggiornamento delle statistiche\n");
		//setto il messaggio da inviare
		setHeader(&msg->hdr, OP_OK, server);
		printf("%s\n",s);
		setData(&msg->data, "", s, strlen(s)+1);
}
Se provo a stampare la stringa prima della terminazione della funzione ottengo il risultato che mi aspetto ovvero la lista dei nomi. Se, invece, provo a stampare la stringa dal thread dopo la terminazione della funzione mi viene stampato NULL.

Questo è il codice della funzione make_connected_user_list
int make_connected_user_list(char *s){
    int err=-1, dim=0, i=0, namesize=0;
    //prendo la lock per l'array connected_clients
    if((err=pthread_mutex_lock(&mux_connected_clients))!=0){
	errno=err;
	fprintf(stderr,"Errore nel prendere la lock; Funzione connect_user; Variabile connected_clients\n");
	perror("lock");
	return -1;
    }
    //calcolo la dimensione del nome, alloco lo spazio necessario nel buffer e gli concateno il nome del client
    for(i=0; i<config.MaxConnections; i++){
	if(connected_clients[i].stato==1){
	    namesize=strlen(connected_clients[i].name)+2;
	    dim=dim+namesize;
	    s=realloc(s, dim*sizeof(char));
	    if(s==NULL){
		fprintf(stderr, "Errore durante la riallocazione della lista di utenti connessi\n");
		return -1;
	    }
	    strncat(s, connected_clients[i].name, namesize-1);
	    strncat(s, "-", 1);
	}
    }
    s[(strlen(s)-1)]='\0';
    //rilascio la lock per l'array connected_clients
    if((err=pthread_mutex_unlock(&mux_connected_clients))!=0){
	errno=err;
	fprintf(stderr,"Errore nel rilasciare la lock; Funzione connect_user; Variabile connected_clients\n");
	perror("lock");
	return -1;
    }
    return 0;
}
Qualcuno sa dirmi dove sbaglio?

7 Risposte

  • Re: [C] stringa=NULL dopo return funzione

    Se il puntatore che passi deve essere provocato dalla funzione, allora lo devi passare per puntatore. Quindi l'argomento sarà un doppio puntatore.

    funzione(char **s)

    e la chiamerai con

    funzione(&s);
  • Re: [C] stringa=NULL dopo return funzione

    Grazie mille sei stato gentilissimo
  • Re: [C] stringa=NULL dopo return funzione

    Eseguendo il programma con valgrind mi da questi errori che non riesco a capire a cosa sono duvuti
    Conditional jump or move depends on uninitialised value(s)
    ==4502==    at 0x4C309D6: strcat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==4502==    by 0x10E70D: make_connected_user_list (chatty.c:1743)
    ==4502==    by 0x111336: worker (chatty.c:2823)
    ==4502==    by 0x4E416C9: start_thread (pthread_create.c:333)
    ==4502==  Uninitialised value was created by a heap allocation
    ==4502==    at 0x4C2DA5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==4502==    by 0x4C2FDDF: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==4502==    by 0x10E6A8: make_connected_user_list (chatty.c:1738)
    ==4502==    by 0x111336: worker (chatty.c:2823)
    ==4502==    by 0x4E416C9: start_thread (pthread_create.c:333)
    ==4502== 
    ==4502== Conditional jump or move depends on uninitialised value(s)
    ==4502==    at 0x4C30D38: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==4502==    by 0x111481: worker (chatty.c:2839)
    ==4502==    by 0x4E416C9: start_thread (pthread_create.c:333)
    ==4502==  Uninitialised value was created by a heap allocation
    ==4502==    at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==4502==    by 0x10E7B7: make_connected_user_list (chatty.c:1754)
    ==4502==    by 0x111336: worker (chatty.c:2823)
    ==4502==    by 0x4E416C9: start_thread (pthread_create.c:333)
    
    La funzione è quella di prima ma uso all'interno una stringa di appoggio per la creazione della lista di nomi.
    
    1723:int make_connected_user_list(char **string){
    1724:    int err=-1, dim=0, i=0, namesize=0;
    1725:    char *s=NULL;
    1726:    //prendo la lock per l'array connected_clients
    1727:    if((err=pthread_mutex_lock(&mux_connected_clients))!=0){
    1728:		errno=err;
    1729:		fprintf(stderr,"Errore nel prendere la lock; Funzione connect_user; Variabile connected_clients\n");
    1730:		perror("lock");
    1731:		return -1;
    1732:    }
    1733:   //calcolo la dimensione del nome, alloco lo spazio necessario nel buffer e gli concateno il nome del client
    1734:    for(i=0; i<config.MaxConnections; i++){
    1735:		if(connected_clients[i].stato==1){
    1736:		    namesize=strlen(connected_clients[i].name)+2;
    1737:		    dim=dim+namesize;
    1738:		    s=realloc(s, dim*sizeof(char));
    1739:		    if(s==NULL){
    1740:				fprintf(stderr, "Errore durante la riallocazione della lista di utenti connessi\n");
    1741:				return -1;
    1742:	 	   }
    1743:		    strcat(s, connected_clients[i].name);
    1744:		    strncat(s, "-", 1);
    1745:		}
    1746:    }
    1747:    //rilascio la lock per l'array connected_clients
    1748:    if((err=pthread_mutex_unlock(&mux_connected_clients))!=0){
    1749:		errno=err;
    1750:		fprintf(stderr,"Errore nel rilasciare la lock; Funzione connect_user; Variabile connected_clients\n");
    1751:		perror("lock");
    1752:		return -1;
    1753:    }
    1754:   *string=(char*)malloc(strlen(s)*sizeof(char));
    1755:    strncpy(*string, s, strlen(s)-1);
    1756:    *string[strlen(s)]='\0';
    1757:    free(s);
    1758:    return 0;
    1759:}
    Il worker è il thread da cui chiamo la funzione make_connected_user_list.
    Ho aggiunto il numero della riga al codice e spero che sia identato bene
  • Re: [C] stringa=NULL dopo return funzione

    Se metti i numeri di linea vien difficile copiare e incollare il codice per provarlo ...
  • Re: [C] stringa=NULL dopo return funzione

    Chiedo scusa, ecco il codice:
    int make_connected_user_list(char **string){
        int err=-1, dim=0, i=0, namesize=0;
        char *s=NULL;
       //prendo la lock per l'array connected_clients
       if((err=pthread_mutex_lock(&mux_connected_clients))!=0){
          errno=err;
          fprintf(stderr,"Errore nel prendere la lock; Funzione connect_user; Variabile connected_clients\n");
          perror("lock");
          return -1;
       }
       //calcolo la dimensione del nome, alloco lo spazio necessario nel buffer e gli concateno il nome del client
       for(i=0; i<config.MaxConnections; i++){
          if(connected_clients[i].stato==1){
              namesize=strlen(connected_clients[i].name)+2;
              dim=dim+namesize;
              s=realloc(s, dim*sizeof(char));
              if(s==NULL){
                fprintf(stderr, "Errore durante la riallocazione della lista di utenti connessi\n");
                return -1;
              }
              strcat(s, connected_clients[i].name);
              strncat(s, "-", 1);
          }
        }
        //rilascio la lock per l'array connected_clients
        if((err=pthread_mutex_unlock(&mux_connected_clients))!=0){
    	 errno=err;
        	 fprintf(stderr,"Errore nel rilasciare la lock; Funzione connect_user; Variabile connected_clients\n");
       	 perror("lock");
        	return -1;
        }
        *string=(char*)malloc(strlen(s)*sizeof(char));
        strncpy(*string, s, strlen(s)-1);
        *string[strlen(s)]='\0';
        free(s);
        return 0;
    }
  • Re: [C] stringa=NULL dopo return funzione

    Premesso che potevi fare tutto senza puntatore temporaneo (potevi usare solamente string), comunque ti indico le righe sbagliate nel tuo codice (con la versione corretta) ... comprendi tu cosa non va

    char *s = (char *)malloc(sizeof(char));
    *s = '\0';

    strcat(s, "-");

    (*string)[strlen(s)-1] = '\0';
  • Re: [C] stringa=NULL dopo return funzione

    Grazie mille ho risolto!
Devi accedere o registrarti per scrivere nel forum
7 risposte