Newsgroup: it.comp.lang.delphi
Titolo: type of type

In una unit definisco due tipi:
primotipo = array [1..5] of byte;
secondotipo = array [1..100000] of primotipo;
Adesso se nella unit assegno come risultato di una funzione primotipo la 
compilazione va a buon fine, se invece assegno come risultato secondotipo, 
genera una access violation.
Qualche delphista di buon cuore mi potrebbe schiarire le idee?
Grazie
-- 
F&R 

 genera una access violation.
Il problema č nella grandezza dei dati.  Il valore di ritorno di una
funzione deve poter stare nello stack e lo stack č decisamente piů piccolo
di quella dimensione che dichiari.  In ogni caso, la tua tecnica č in
tutti i casi sconsigliabile.  Meglio dichiarare:
procedure pippo(var a: secondotipo);
In questo modo viene implicitamente passato solo un puntatore all'area di
memoria.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 tutti i casi sconsigliabile.  Meglio dichiarare:
Forse Andrea ha ragione ma non sono del tutto convinto. Prova a dimensionare 
da 1..50 il secondotipo, se fosse un problema di stack dovrebbe evitare 
l'errore.
Pittosto controlla di non uscire dal range degli indici, eventualmente nelle 
opzioni del project, compiler abilita Range Checking.
Ciao Giorgio 

> di quella dimensione che dichiari.
In effetti Andrea Laforgia ha ragione.
Me ne ero gia' reso conto da solo, analizzando meglio il debug.
Piuttosto, giusto per completezza, volevo fare una precisazione sulla sua 
risposta, dove lui dice "Meglio dichiarare: procedure pippo(var a: 
secondotipo);"
In effetti io avevo parlato di risultato della funzione, ed ho risolto 
dichiarando un altro tipo "Psecondo tipo = ^secondotipo" e quindi 
dichiarando
"function ... (....) : Psecondotipo".
Cosi' in effetti il risultato sta nello stack ed il compilatore non genera 
l'errore di stack overflow .
Grazie a tutti.
-- 
F&R

 Forse Andrea ha ragione ma non sono del tutto convinto. 
Il problema è quello, invece.  I parametri formali e i dati locali alle
funzioni (compresi i valori di ritorno) risiedono nello stack.


 l'errore di stack overflow .
Secondo me e' preferibile la sua soluzione, perche' restituendo un 
puntatore e' facile cadere nel classico errore di restituire un 
puntatore ad una variabile locale, che appena usciti dalla funzione 
viene distrutta e quindi il puntatore finisce per puntare a una zona di 
memoria non valida:
function pippo(...) : PSecondoTipo;
var
   ST : SecondoTipo;
begin
   ...
   Result := @ST;
end;
ciao
Giacomo

 l'errore di stack overflow .
Non genera eccezione, perché quello che risiede sullo stack è un puntatore
(su un'architettura a 32 bit sostanzialmente sono solo 4 byte, anche se la
memoria puntata fosse di un giga).  E' una soluzione sostanzialmente
identica a quella che suggerivo io, anche se la mia la ritengo più pulita
(sostanzialmente il puntatore è mascherato), meno C-like, meno error-prone
e molto più Pascal-like ;-)
In generale, c'è la tendenza nei linguaggi della generazione OO (Delphi,
C++, Java, ecc..) ed evitare i puntatori come la peste (essendo fonte
potenziale di grandi guai) ed affidarsi invece a costrutti come i
"reference" o i passaggi per riferimento.


 e molto piů Pascal-like ;-)
Premetto che avrei voluto chiederlo in privato ad Andrea, per non ingombrare 
il newsgroup
con quella che probabilmente e' una domanda da principiante, ma non ho 
trovato il suo indirizzo email.
Vorrei compredere meglio la sua soluzione: se io ho bisogno di un valore
di ritorno, e quindi utilizzo una function per ottenere come risultato il
puntatore ad una variabile (globale, naturalmente) di tipo "secondotipo", 
come raggiungo lo stesso scopo con una procedure?
Grazie.
-- 
F&R
Ferdinando Fiandaca

 come raggiungo lo stesso scopo con una procedure?
Una funzione che restituisca un puntatore generalmente alloca memoria per
il puntatore al suo interno, quindi non restituisce l'indirizzo di una
variabile globale (non avrebbe molto senso questo giro, visto che la
variabile è globale) ma l'indirizzo della memoria allocata.  La memoria
verrebbe poi deallocata altrove (dal chiamante presumibilmente).
Un esempio:
function AllocateMemory(const ASize: Integer): Pointer;
var
  P: Pointer;
begin
  GetMem(P, ASize);
  Result := P;
end;
...
var
  P: Pointer;
P := AllocateMemory(1024),
...
.. // do something
...
FreeMem(P);
In alternativa, si potrebbe avere:
procedure AllocateMemory(var P: Pointer; ASize: Integer);
begin
  GetMem(P, ASize);
end;
....
var 
  P: Pointer;
AllocateMemory(P, 1024);
...
.. // do something
...
FreeMem(P);
