Newsgroup: it.comp.lang.c
Titolo: come fare malloc dentro ad una funzione  ?

Cio' che vorrei fare io e' una cosa di codesto genere:
void init(int* i)
{
    i=(int*)malloc(sizeof(int));  // [*2]
    *i=10;
}
int main(void)
{
    int* MyInt;
   // MyInt=(int*)malloc(sizeof(int)); // [*1]
    init(MyInt);
    printf("%d\n",*MyInt);
}
Nella riga (commentata) con [*1] c'e' la situazione normale per la 
malloc e se decommento quella parte e commento la riga con [*2] il tutto 
funziona correttamente, come giusto che sia.
Se invece tengo la cosa cosi' nella variabile MyInt ottengo un valore 
immondo (nel senso che non ha un valore minimamente vicino a 10).
Grazie anticipatamente.
Ciao
	MaX

Ciao, YattaMaX!
Il giorno 05/07/2004 alle ore 18:55 hai scritto:
 Y> Cio' che vorrei fare io e' una cosa di codesto genere:
 Y>
 Y> void init(int* i)
 Y> {
 Y>     i=(int*)malloc(sizeof(int));  // [*2]
 Y>
 Y>     *i=10;
 Y> }
 Y>
 Y> int main(void)
 Y> {
 Y>     int* MyInt;
 Y>
 Y>    // MyInt=(int*)malloc(sizeof(int)); // [*1]
 Y>
 Y>     init(MyInt);
 Y>
 Y>     printf("%d\n",*MyInt);
 Y> }
A occhio:
void init(int** i)
{
  *i = (int *)malloc(sizeof(int));
  *(*i) = 10;
}
int main(void)
{
  int *MyInt;
  init(&MyInt);
  printf("%d\n",*MyInt);
}
Con beneficio d'inventario.
Bye
-- 
Fear is the path to the Dark Side.
http://www.maccasoft.com

 
Okay, funziona !! :)
Pero',ho diciamo l'obblico :( di avere la funzione init dichiarata come 
prima "void init(int* i)" senza la possibilita' di prendere decisioni 
personali :(
C'e' una soluzione ?
Grazie di tutto
	MaX

Ciao, YattaMaX!
Il giorno 05/07/2004 alle ore 20:10 hai scritto:
 Y> Pero',ho diciamo l'obblico :( di avere la funzione init dichiarata come
 Y> prima "void init(int* i)" senza la possibilita' di prendere decisioni
 Y> personali :(
Sento un tremito nella Forza, l'ultima volta che l'ho sentito ero in
presenza di un universitario che tentava di farsi fare l'esame a scrocco.
 Y> C'e' una soluzione ?
Si c'e'. Se hai capito perche' le modifiche che ho fatto funzionano, sarai
anche in grado di trovare la soluzione.
Bye
-- 
There is no passion; There is serenity.
http://www.maccasoft.com

 C'e' una soluzione ?
Risposta breve:
No, devi avere delle funzioni del tipo:
void init(int **i);
int *init(void);
Risposta meno breve:
Dipende da quante porcate vuoi mettere nel codice. Il problema e` dovuto
al fatto che in C i parametri sono sempre passati per copia; in questo
caso si puo` aggirare giocando sporco, ma la soluzione sarebbe brutta e
non portabile, oltre che concettualmente sbagliata. Visto che sei agli
inizi non mi pare il caso di farti vedere una simile oscenita` ;)
Luca
-- 
Home: 
http://kronoz.cjb.net
Se il  destino di un uomo  e` annegare, anneghera` anche  in un bicchier
d'acqua.
Proverbio yddish

 
Beh no, non mi sto facendo fare l'esame a scrocco, sarebbe proprio una 
bella cosa se un esame fosse solo quello li ! :)
Ho delle specifiche, si, pero' quella cosa la sto facendo perche' IO di 
MIA spontanea volonta' mi sto intestardendo nel farlo !!
Potrei anche fregarmene di mio e saltare questa cosa semplicemente non 
facendola, pero' penso possa risultare utile imparare la questione 
illustrata sopra.
Ho provato anche con:
void init(int* i)
{
    int** u=&i;
    *u=(int*)malloc(sizeof(int));
    *(*u)=10;
}
ma senza risultati :(
Se mi vuoi dare una mano okay, grazie, altrimenti grazie lo stesso.
Ciao
	MaX
PS:
La funzione non sarebbe neppure dichiarata in quella maniera, ma init 
prenderebbe in input un (void* ptr), che punta ad una struttura, pensi 
che se mi volessi far fare un esame a "scrocco" avrei messo una 
dichiarazione semplificata o forse avrei messo TUTTO ?
Io sto solo cercando di risolvere un annoso dubbio !!

 al fatto che in C i parametri sono sempre passati per copia; 
Si e' vero, ma in questo caso gli sto passando un puntatore.
Cio' che mi viene in mente e' che essendo in uno scope piu' alto, cisto 
che e' dentro ad un'altra funzione e il C e' a scope statico, quando 
esce dalla funzione ditrugge il riferimento alla variabile puntatore e 
quindi si viene a creare una dagling references.
Pero' vorrei riuscirlo a farlo, se prima avevo anche una necessita', ora 
mi e' venuta una pulce immensa nell'orecchio, che mi da un fastidio cane 
!!!  ( pulce-cane :)  )
Ciao
	MaX

 Si e' vero, ma in questo caso gli sto passando un puntatore.
Si`, stai passando un puntatore *per copia*.
void foo(int i) {
        i++;
}
int x = 1;
foo(x);
printf("%d\n", x);
Suppongo che non ti stupisca il fatto che la printf stampi '1', giusto?
L'intero x viene copiato prima di essere usato dalla funzione.
void foo(int *i) {
        i = malloc(sizeof(int));
}
int x = NULL;
foo(x);
printf("%d\n", x);
Questo esempio e` concettualmente identico a quello sopra. L'oggetto (in
questo caso un int *) viene copiato prima della chiamata a funzione, la
funzione opera su una copia locale. Cosi` come prima il cambiamento
fatto ad /i/ non veniva visto dal chiamante, allo stesso modo le
modifiche fatte al puntatore non si propagano al chiamante.
In entrambi i casi si ricorre ad un livello di indirezione ulteriore
(ie. tramite il puntatore risalgo all'oggetto puntato): nel primo caso
si usa un puntatore ad int, nel secondo si usa un puntatore a puntatore
a int.
Nel tuo caso puoi ricorrere ad un paio di cast, ma la soluzione funziona
"per caso" (ie. perche` l'hw lo permette):
void foo(int *i) {
        int **ii = (int **)i;
        *ii = malloc(sizeof(int));
        *ii = 10;
}
int *i;
foo((int *)&i);
Nota che il C non garantisce che il cast tra puntatori diversi (void
escluso) mantenga tutte le informazioni necessarie. Sicuro che non puoi
cambiare la funzione? A me sembra un'interfaccia sbagliata.
Luca
-- 
Home: 
http://kronoz.cjb.net
Non capisco tutta questa eccitazione per il Multitasking: 
io sono anni che leggo in bagno.

        *ii = 10;
         ^^^^^^^^
Manca una dereferenziazione:
        **ii = 10;
Luca
-- 
Home: 
http://kronoz.cjb.net
La vasca da bagno fu inventata nel 1850, il telefono nel 1875.
Se fossi vissuto nel 1850, avrei potuto restare in vasca per 25 anni
senza sentir squillare il telefono

Avrei potut fare anche cosi:   (non che non ci avessi pensato prima)
void init(int* i)
{
    int* u=(int*)i;
    *u=10;
  }
  int main(void)
  {
     int MyInt;
     init(&MyInt);
     printf("%d\n",MyInt);
  }
Ma a me interessava fare la malloc dentro a init per fare il controllo 
dell'avvenuta allocazione e poi perche' mi era venuta quella 
curiosita',ma visto che pare non essere possibile farlo, lo terro' cosi' !!
(teoricamente init tornerebbe un int: 1 se tutto ok, altrimenti 0).
Ciao
	MaX