Newsgroup: it.comp.lang.c++
Titolo: Curiosità veloce veloce (dichiarazione stringhe)

Non sono sicuro di essere nel posto giusto, a fare domande strettamente 
legate al C, ma in fondo ï¿œ un sottoinsieme proprio del c++. Comunque, se 
non ï¿œ il caso, per favore fatemelo notare ;)
in breve:
char str[LENGTH];
ï¿œ totalmente equivalente a
char* str = malloc( LENGTH * sizeof(char) );
?
E se non lo sono, che differenza fa usare una delle due scritture?
Ho il vago sospetto che cambi qualcosa a livello di memorizzazione, ma 
su questa "roba basso livello" sono scarso, e appunto mi piacerebbe 
approfondire ;)
Grazie in anticipo,
M.

 char* str = malloc( LENGTH * sizeof(char) );
La differenza e' che nel primo caso lo spazio e' allocato e distrutto
automaticamente all'entrata e all'uscita dello scope corrispondente.
Nel secono caso viene allocato in uno spazio globale quindi devi
pensarci tu a distruggerlo con una chiamata a free()
Ultima nota: in genere in C++ si preferisce usare new e dispose
al posto di malloc e free che sono li appunto per compatibilita col C
ciao
Giacomo

 
saluti
M

 Anche questo sapevo, ma non sono new e delete() ?
Arg! Certo! dispose e' quella del pascal! Sono cose che succedono a
passare troppo da un linguaggio all'altro! :D
ciao
Giacomo

 Giacomo
Eheheh tranquillo, ti capisco benissimo ;)
tutto chiaro, grazie ancora, e alla prossima
saluti
M.

 in memoria?
ti ha già risposto Giacomo, malgrado imho da quello che 
chiedi non sono così sicuro se tu voglia sapere lo SCOPE o 
il LIFETIME delle variabili.
Per quanto riguarda il life time, non posso che ribadire 
quanto detto da Giacomo : static è il più persistente tipo 
di oggetti allocabili, dato che allocati (e inizializzati 
sempre e comunque) prima di entrare nel punto di ingresso 
del codice scritto a mano (salvo mostruosi raggiri) e 
vengono rilasciati dopo che il programma è terminato e 
rilascia ogni risorsa usata bene all'OS.
Circa lo scope, static ha un carattere più ambiguo, ossia : 
se il modificatore è applicato a variabili automatiche, non 
ne modifica lo scope in alcun modo, e la visibilità rimane 
la stessa (quindi anche con la possibilità di oscuramento da 
parte di nomi uguali ma dichiarati più esternamente), mentre 
il lifetime rimane cmq persistente.
Se invece è applicato a termini globali, allora static 
restringe anche lo scope, che diventa a livello di singolo 
FILE mentre un globale non static (linking extern) estende 
la propria visibilità all'intera unità di compilazione (al 
progetto diciamo). Static quindi in questo caso restringe.
Credo che da quando esistono i namespace questo scopo sia 
diventato obsoleto, ma rimane l'utilità di poter contare su 
oggetti inizializzati prima ancora di entrare in main().
Ah ... quanto ai dinamici (new, malloc) non hanno un 
lifetime predeterminato, semplicemente è lasciato a totale 
cura del programmatore, quindi non sono sinonimo di static.
Inoltre la memoria dinamica può e può non essere reperita 
generando eccezioni intercettabili. Una risorsa statica, se 
si trova bene, il programma parte e ci puoi sempre contare 
che esista, se non si trova, il programma abortisce in 
maniera irreversibile.
ciao
Soviet


 
Saluti,
M.

tilde ha scritto:

  P.S.: voi di usenet siete davvero fighi, complimenti.

 P.S.: voi di usenet siete davvero fighi, complimenti.
A proposito di usenet giusto un consiglio: quando quoti butta via quello 
che non serve :)
Aiuta a rendere tutto pi� leggibile
Ciao

GM ha scritto:

Sir yes sir!
M.

 niente se sto chiedendo troppo
nel senso che quando allochi risorse dinamiche metti sempre 
in conto che possano anche non essere trovate. Il programma 
non si pianta per questo (a meno che poi non tenti di 
usarle) ma ti informa, in vario modo, che non ha saputo 
trovarle e ora il problema te lo gestisci te. Come ti 
informa dipende. Malloc ti ritorna un NULL, new lancia un 
eccezione, ma in ogni caso sta a te poi decidere se 
terminare o tentare che so, di usare meno memoria, ad es. 
salvando i dati in un file (es.).
Coi dati statici questo non avviene. Ovunque hai sempre la 
garanzia che esistono e sono persistenti, perché li hai 
pagati in anticipo. Se l'unità di esecuzione dell'OS non li 
trova in alcun modo, la GUI ti spara un messaggio di errore 
sul fatto di avere memoria insufficiente e il tuo programma 
non parte per niente.
riciao


 il tuo programma non parte per niente.
Ah, quindi 1-0 per le dichiarazioni statiche =)
Ho un'altra domanda, se non ï¿½ proprio approfittarsi: gestire 
dinamicamente gli oggetti ï¿½ sempre piï¿½ performante? Un programma C che 
usa esclusivamente risorse dinamiche e puntatori (ponendo che sia 
bug-free) ï¿½ piï¿½ scattante di uno che usa anche dichiarazioni "normali" 
(specialmente per i tipi base)?
 > riciao
 >
ciao!
M.

tilde ha scritto:

Ora ho capito, me l'avevi spiegato prima:
Se non static, non c'ï¿½ bisogno di extern, ï¿½ proprio globalmente visibile 
(logicamente), invece static riduce la visibilitï¿½ a livello di file.
Testaccia -.-
M.

 M.
Ricapitolando:
Variabile dichiarata in una funzione:
di default è auto ed è nello stack (non esiste piu quando la funzione
ritorna).
Se la variabile è dichiarata static allora la variabile NON è né nello
stack né nell'heap, ma in un'altra zona di memoria ancora.
Variabile dichiarata esterna ad una funzione:
di default è globale ovvero visibile a tutto il progetto
la variabile NON è né nello stack né nell'heap, ma nella stessa zona
di memoria di cui sopra.
Se la variabile è dichiarata static allora il suo scope è limitato al
file in cui è dichiarata (non è piu visibile a tutto il progetto).
Come vedi static assume significati diversi tra loro a seconda del
contesto.
Un ultimo chiarimento su extern con un esempio:
hai un progetto fatto da piu file, ad esempio pippo.c e pluto.c, e
pippo.c contiene la variabile globale (non dichiarata static) "int
minni".
Quando il compilatore va a compilare pippo.c non avrà problemi ogni
volta che inconterà la variabile "minni" a capire di cosa si tratta,
poiché è stata dichiarata nello stesso file.
Quando il compilatore va a compilare pluto.c ed incontra la variabile
"minni" ha bisogno di sapere di cosa si tratta, e per questo si usa
"extern int minni;", che indica al compilatore che "minni" è di tipo
int, ed è definita da qualche altra parte nel progetto (cioè non
preoccuparti di dov'è la variabile ora, perché ci penserà il linker a
popolare correttamente il suo indirizzo)

 popolare correttamente il suo indirizzo)
Ci voleva, ottimo!
M

Giacomo ha scritto:

Ecco, bravissimo, sei riuscito con meno parole a spiegare 
meglio di me.
Spero che ora Tilde si sia convinto di quanto tentavo di 
dirgli, che quella keyword è un filo ambigua e contesto 
dipendente e che contrariamente a quanto suggerisce il nome, 
può ANCHE restringere lo scope. Col tuo esempio diventa evidente
ciao
Soviet

 M.
ciao
Soviet

 sprecherai un 160 byte
perché ? E ancora, ma non è OS-dependant o almeno libc++-dependant ?
un'implementazione furba della new dovrebbe richiedere al sistema
operativo una quantita piu grande di memoria (paddata magari al
multiplo della dimensione minima) alla prima allocazione, e poi
gestire lo spezzettamento per le rimanenti 9 allocazioni senza rompere
ogni volta al SO

 ogni volta al SO
Se le fai contigue forse si. Rimane il discorso 
dell'over-space nella lista linkata o altra struttura dati 
atta a tracciare l'esistenza di blocchi, supportare la 
ricerca etc. Anche se con new delete si vedono molto meno (o 
punto) rispetto a malloc free e tutte le altre numerose 
funzioni di heap (heapchk, heapchknode, heapwalk e ce 
n'erano parecchie in C), internamente non può dare cose 
troppo differenti.
Cmq, ultima cosa su sto thread poco IT ... Forse ho intuito 
cosa intendeva dire l'OP parlando dell'efficienza della ram 
dinamica e puntatore vs. l'uso dello stack.
Forse il discorso che aveva in mente era circa la possibile 
inefficienza della COPIA di dati ingombranti passati come 
argomenti e valori di ritorno, dentro e fuori lo stack.
Ma questo è un errore di design (quando lo è), non una 
lentezza dello stack. Passare reference e puntatori è più 
efficiente a presindere da dove sia collocato l'oggetto 
puntato : l'importante è non eseguire copie avanti e 
indietro. Se invece non era questo che intendeva ... boh, lo 
chiarirà lui
ciao
Soviet

 stack n� nell'heap, ma in un'altra zona di memoria ancora.
Dopo di che, per dirla tutta, lo standard definisce il ciclo di vita
delle variabili *non* come l'implementazione le piazza in memoria. Il
fatto che siano su stack e/o heap e/o altrove � puramente la convenzione
implementativa di praticamente tutte le piattaforme.
-- 
-riko