Go Down

Topic: Ottimizzare la gestione delle stringhe (Read 10534 times) previous topic - next topic

overmike

Mi avete "allocato" e pertanto dovete sopportarmi.
Prima con Guglielmo, poi Mauro ho inteso il significato del messaggio, ma chiedo una verifica.

Ecco il ragionamento che ho fatto nello sviluppare il codice di questa funzione:
- tramite il parametro "VarVal" passo il dato
- definisco hex in modo locale
- eseguo il calcolo
- restituisco la stringa
- termine della funzione

Tipicamente a questo punto il codice che ha chiamato la funzione utilizza il dato  o come condizione per il classico "if" oppure lo passa ad una variabile globale per elaborazioni successive.

Perchè dico io, dovrei preoccuparmi di perdere "hex", quando alla successiva chiamata della funzione tutto dovrebbe ripetersi,
o no?
Proprio perchè ho dichiarato "hex" locale, mi aspetto che la stessa venga distrutta e restituito lo spazio rispettivo.
Dove sbaglio?

nid69ita

#31
Mar 05, 2014, 02:30 pm Last Edit: Mar 05, 2014, 02:33 pm by nid69ita Reason: 1
Non hai capito, il problema NON è dentro la tua funzione ma l'assegnazione che farai usandola:
Code: [Select]
char * pStr=HexOut (65);

Entri nella funzione, viene allocata variabile hex, 2 char. Ci scrivi dentro e fai return del puntatore ad esso. Solo che all'uscita il puntatore lo assegni a pStr.  Ora pStr punterà ad una zona di memoria ora considerata free, libera e che nessuno vieta di sovrascrivere da parte di un altro pezzo di codice (esempio chiami un'altra funzione con variabili locali)
my name is IGOR, not AIGOR

gpb01

@ Nid : Esatto ! :)

@ overmike : come ti ha spiegato Nid, dimentichi che stai lavorando con dei "puntatori".

Quando ritorni un "char *" tu stai ritornando un puntatore ad tipo char.  Il tuo tipo char è la variable hex (è un array di char), che, quando la funzione esce, non esiste più e quindi ... come vai ad usare un puntatore a qualche cosa che non esiste più ???  XD

Guglielmo
Search is Your friend ... or I am Your enemy !

nid69ita

#33
Mar 05, 2014, 02:37 pm Last Edit: Mar 05, 2014, 02:41 pm by nid69ita Reason: 1
In alternativa puoi definire la funzione passando anche il buffer da usare:
Code: [Select]
char buf[3];
HexOut (65,buf);

Il secondo parametro è dove andrai a scrivere, perciò non più in hex locale ma nel parametro hex
Code: [Select]
void HexOut (byte VarVal, char hex[])
{ byte v;
 hex [0]='\0'; hex [1]='\0'; hex [2]='\0';  // azzera buffer

 v = VarVal >> 4;           // sposta nible alto (7-4) a (3-0)                  
 if (v > 9) v += 7;         // 10-15 > A-F
 hex [0]= v + 0x30;         // conv. in alfan. e salva
 v = VarVal & 0xF;          // isola nible basso
 if (v > 9) v += 7;         // 10-15 > A-F
 hex [1]= v + 0x30;         // conv. in alfan. e salva
}


Oppure fai come detto da Guglielmo nel post precedente usando static
my name is IGOR, not AIGOR

overmike

Opto per la soluzione di Guglielmo.
Conoscevo gia' la funzionalita' di STATIC, ma mai l'avrei utilizzata a tale scopo.

Peccato non abitiate in zona, perche' vi avrei offerto caffe' e brioche, mi sento in debito!

Renzo

gpb01


Peccato non abitiate in zona, perche' vi avrei offerto caffe' e brioche, mi sento in debito!


XD XD XD Grazie, come se lo avessimo preso !

Purtroppo anche io ... non trovo mai nessuno che sta da queste parti ...  :smiley-roll:

Guglielmo
Search is Your friend ... or I am Your enemy !

nid69ita

#36
Mar 05, 2014, 03:16 pm Last Edit: Mar 05, 2014, 03:34 pm by nid69ita Reason: 1
Occhio però che con static, usi la tua funzione, ottieni il numero in esa, e devi usarlo prima di riusare di nuovo la tua funzione.
Con static la tua variabile locale hex è comunque una ed unica nel programma.
Se fai:
Code: [Select]
char *ps1=HexOut(64);    // 64=>0x40
char *ps2=HexOut(69);    // 69=>0x45

Avrai che ps1 e ps2 puntano alla unica variabile hex che contiene "45"

P.S. si può sapere di che zona sei ?   :)
my name is IGOR, not AIGOR

gpb01

Ma infatti lui NON dovrà assegnarla così, ma usando la strcpy() verso la sua destinazione finale ... XD XD XD

Guglielmo
Search is Your friend ... or I am Your enemy !

nid69ita


Ma infatti lui NON dovrà assegnarla così, ma usando la strcpy() verso la sua destinazione finale ... XD XD XD
Guglielmo

Come si dice, meglio mettere i puntini sulle ï       :smiley-mr-green:    
my name is IGOR, not AIGOR

Maurotec

Quote
Occhio però che con static, usi la tua funzione, ottieni il numero in esa, e devi usarlo prima di riusare di nuovo la tua funzione.


Mi hanno suggerito di scrivere in modo meno dettagliato, ci provo.
Inoltre usando static, come suggerito da gpb01 la funzione è *non* rientrante.
Inoltre non puoi dichiararla inline.

Io seguirei il consiglio di nid.

Ciao.


nid69ita

#40
Mar 05, 2014, 04:37 pm Last Edit: Mar 05, 2014, 04:54 pm by nid69ita Reason: 1
Sempre per i puntini sulle i:    però nel metodo con secondo parametro, se passi un vettore più corto di 3 celle (char) fai una ca...volata   :smiley-mr-green:

Comunque @overmike   sai che la tua funzione potresti sostituirla con questa (spero ci sia in librerie avr):  snprintf
Code: [Select]
char buffer [5];
int cx;
cx = snprintf ( buffer, 5, "%02X", 65);   // almeno 2 cifre, fill con 0 se più corto di 2
// in cx il numero di caratteri (si può anche omettere l'assegnazione a cx)

Qui i formati accettati tra gli apici doppi (che poi sono quelli di printf)

Tutti okay TRANNE quel che riguarda i numeri float, quelli su avr son stati "disabilitati"

EDIT: mi pare ci sia:
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html
my name is IGOR, not AIGOR

gpb01

#41
Mar 05, 2014, 04:52 pm Last Edit: Mar 05, 2014, 04:54 pm by gpb01 Reason: 1

Inoltre usando static, come suggerito da gpb01 la funzione è *non* rientrante.
Inoltre non puoi dichiararla inline.


:smiley-mr-green: :smiley-mr-green: :smiley-mr-green: ... no, ma mo' dimme perché uno dovrebbe fa' rientrante 'na cavolo di funzioncina che converte un byte in HEX  XD XD XD XD XD XD

C'avete la mente malata ...  :smiley-mr-green: XD :smiley-mr-green: XD :smiley-mr-green: XD :smiley-mr-green:

Guglielmo

P.S. : Comunque ... mi sto ammazzando dalle risate ...
Search is Your friend ... or I am Your enemy !

gpb01

Lock ... ...

... ma mo' ... questo ... che c'entra ???  :smiley-eek: :smiley-eek: :smiley-eek:

Guglielmo
Search is Your friend ... or I am Your enemy !

nid69ita

#43
Mar 05, 2014, 04:58 pm Last Edit: Mar 05, 2014, 05:02 pm by nid69ita Reason: 1
@Lock, però passi lo struct o il puntatore al tuo struct?  
Mi pare (la memoria!!!) che gli struct vengono passati non per referenza (puntatore) ma per valore, quindi uno struct che contiene un array di 50 byte è pesante come parametro.

Poi, se devi tu mettere un membro con size di qualcosa, cosa cambia a obbligare le funzioni che si fanno ad avere un ulteriore parametro con la size?
Io ad esempio so che esiste la strcpy ma anche la strncpy  come esiste la sprintf ma anche la snprintf.  Quelle con la n vogliono un parametro con la dimensione del vettore. Io utilizzo sempre quelle con la n.
my name is IGOR, not AIGOR

gpb01


centra con questa osservazione qui sopra!


Ahhhhhh ... l'hai presa appena, appena ... alla larga ...  XD XD XD XD XD XD

Guglielmo
Search is Your friend ... or I am Your enemy !

Go Up