erlug
[Top] [All Lists]

Re: [Erlug] programma

To: erlug@xxxxxxxxxxxxxx
Subject: Re: [Erlug] programma
From: munehiro <munehiro@xxxxxxxxxxxxxxxx>
Date: Fri, 26 Apr 2002 20:31:17 +0200
On Fri, Apr 26, 2002 at 04:55:40PM +0200, Simone Saravalli wrote:
> Salve a tutta la lista,
>    ho uno dei miei soliti problemini con il C; questa volta è piuttosto duro
> e non so come risolverlo. Causa esame tra non molto tempo, mi
> servirebbe sapere come si fa a copiare all'interno di una stringa, che si
> trova in una funzione A, ad esempio, un'altra stringa, ottenuta come
> valore di ritorno da una funzione B.

non puoi ritornare una stringa con una funzione

> La funzione B viene richiamata dalla
> A e mi fornisce per l'appunto una stringa di 4 caratteri che dovrei
> ricopiare in un'altra stringa presente nella prima funzione.
> Come faccio?

tre soluzioni

la peggiore

void a(void) {
        /* un array (5 posti, 4 per i caratteri e uno per lo \0) e un puntatore 
*/
        char ret[5];
        char *ptr;

        /* chiamo la funzione e ottengo un puntatore ad un'area di memoria
         * statica
         */
        ptr = b();

        /* la copio nel mio buffer ret, stando attento a non sforare */
        strncpy(ret,ptr,4);
        
        /* metto a zero l'ultimo byte */
        ret[4]=0;

        /* stumpa */
        printf("%s\n",ret);
}

char *b(void) { 

        /* lo dichiaro static, non va nello stack e quindi non viene
         * rimosso all'uscita dalla funzione, di conseguenza il puntatore
         * a tale buffer e' sempre valido fino all'uscita del programma
         */     
        static char buffer[5];

        /* la riempio con qualcosa */
        snprintf(buffer, 5, "ciao" );

        /* ritorno il puntatore */
        return buffer;
}


la migliore


void a(void) {
        /* un bell'array di 5 caratteri */
        char ret[5];
        
        /* metto a zero il primo elemento (stringa vuota) */
        ret[0] = 0;

        /* chiamo b passando il mio array e la sua lunghezza come parametri */
        b(ret, sizeof(ret));

        /* stumpa */
        printf("%s\n",ret);

}

void b(char *buf, unsigned int len) {
        
        snprintf(buf, len, "ciao");
        
}


la sadica

void a(void) {
        /* un puntatore */
        char *ptr;

        /* chiamo la funzione */
        ptr = b();

        /* stumpa */
        printf("%s\n",ptr);
        
        /* libera! */

        free(ptr);
}

void b(void) {
        /* allocazione dinamica */      
        char *p = (char *) malloc(5 * sizeof(char));
        
        snprintf(p, 5, "ciao");
        
        return p;

}



l'ultima e' sadica perche' puo' andare bene finche' sei sicuro di tenere
traccia delle allocazioni e deallocazioni in modo preciso e puntuale.
Se inizi a mettere dei controlli o dei salti, e' possibile che allochi senza
deallocare o che deallochi senza allocare. Nel primo caso ottieni un memory
leak, ovvero a lungo andare il tuo programma si magna tutta la virtual memory
a disposizione, nel secondo caso ottieni uno heap corruption, che sicuramente
fa crashare il programma, e nella peggiore delle ipotesi e' un buco di 
sicurezza.

> Devo copiare carattere per carattere, perchè poi la
> seconda funzione viene richiamata più volte e il suo valore di ritorno
> devo incollarlo di volta in volta nella stringa della funzione A
> Ora se faccio, str=nome_funzione (parametri) non va.

ricorda che la prima soluzione e' assolutamente non utilizzabile nel caso
in cui tu usi accesso concorrenziale alla funzione, in casi di multithreading
ad esempio, ma non solo. Se la funzione b torna un valore che cambia in merito
a certe cose, e fai affidamento sul buffer interno, da quando chiami la funzione
a quando leggi il risultato il buffer interno puo' essere stato alterato,
da un altro thread ad esempio, ma anche dallo stesso thread che l'ha chiamata
piu' volte. quindi occhio (e difatti usare variabili statiche e' sempre 
altamente
sconsigliato)

puoi anche ibridare la prima e la terza, allocando e deallocando dentro la
funzione a(), ma non c'e' alcuna differenza rispetto alla prima soluzione,
a parte che il tuo array non e' nello stack ma nello heap, e che, se non
fai free(), ti resta anche dopo aver lasciato la funzione a().

-- 
------------------------------------------------------------

La masturbazione fa male alla memoria e a tante altre cose che ora non ricordo

------------------------------------------------------------



<Prev in Thread] Current Thread [Next in Thread>