View Full Version : [C] - Allocazione Dinamica di strutture
EdgarVillier
07-04-2009, 20:38
Ho trovato su libro un esempio in C che non ho capito, ed'è sull'allocazione dinamica di una struct, nel libro la effettua così :
link t = malloc(sizeof * t);
Dove link è definito nel seguente modo :
typedef struct node* link; struct node{ int info; link next;}
Non capisco la sintassi in malloc(), da quello che sapevo sizeof(tipo_di_dato) accettava in ingresso il tipo di dato e lui ne restituisce la dimensione, ma qui non ho capisco lo si moltiplica per un puntatore a t??
Dalle mie conoscenze precedenti l'allocazione di una struttura aveva la seguente sintassi :
link t =(link) malloc(sizeof(node));
Dove si faceva il cast alla funzione malloc del tipo di dato da allocare con (link).
Grazie a tutti anticipatamente
In questa espressione, se t fosse definito come "link t", ti darebbe per forza un errore... infatti malloc viene eseguito prima, e POI viene copiato il risultato dentro al nuovo "link".
Quindi quel t che sta dentro il malloc è una variabile definita in precedenza :D
Cmq è strano, non dovrebbe essere possibile chiamare due variabili allo stesso modo.
||ElChE||88
07-04-2009, 21:28
link t = malloc(sizeof * t);
t è dichiarato come link, quindi l'espressione equivalente è:
link t = malloc(sizeof * link);
* link dereferenzia link, che è un puntatore e quindi restituisce struct node
link t = malloc(sizeof struct node);
E' un metodo un po' strano per usare la malloc però...
No non è possibile che faccia in quella maniera:
node* t;
questa espressione genera un garbage pointer, tipo 0xcdcdcdcd... t non è inizializzato.
Allo stesso modo, nell'espressione di prima t malloc serve proprio ad inizializzare t, quindi usare t nell'espressione che lo inizializza è quanto di più sbagliato.
deferenziarlo semplicemente manda tutto in crash, nel migliore dei casi...
direi che a questo punto ci serve tutto il codice :D
||ElChE||88
07-04-2009, 22:00
No non è possibile che faccia in quella maniera:
node* t;
questa espressione genera un garbage pointer, tipo 0xcdcdcdcd... t non è inizializzato.
Allo stesso modo, nell'espressione di prima t malloc serve proprio ad inizializzare t, quindi usare t nell'espressione che lo inizializza è quanto di più sbagliato.
deferenziarlo semplicemente manda tutto in crash, nel migliore dei casi...
direi che a questo punto ci serve tutto il codice :D
Prova questo:
#include <stdlib.h>
#include <stdio.h>
typedef struct node* link;
struct node { int info; link next; };
int main()
{
link t1 = malloc(sizeof * t1);
link t2 = malloc(sizeof * t2);
t1->info = 2;
t1->next = NULL;
t2->info = 5;
t2->next = NULL;
printf("%X\n", t1);
printf("%d\n", t1->info);
printf("%d\n", t1->next);
printf("%X\n", t2);
printf("%d\n", t2->info);
printf("%d\n", t2->next);
system("pause");
}
;)
Edit: Comunque il sizeof viene eseguito a compile time, quindi parlare di garbage pointers non ha senso...
Non sapevo che il sizeof fosse eseguito a compile time :D
In più non conoscevo la sua sintassi senza parentesi...
Cmq rimane che il libro è meglio bruciarlo, quella sintassi fa schifo, ed è inutilmente complicata!
Poteva usare direttamente il typename, poteva mettere le parentesi, poteva non fare typedef di un pointer (nascondere che un pointer è un pointer è sbagliato).
Cosa aveva contro
node* t = (node*)malloc( sizeof( node ) );
Si capisce perfettamente cosa fa e fa la stessa cosa. Mah.
||ElChE||88
08-04-2009, 10:47
Cmq rimane che il libro è meglio bruciarlo, quella sintassi fa schifo, ed è inutilmente complicata!
Ma infatti... una cosa del genere scritta in un libro mi fa venire voglia di prendere a martellate nei denti l'autore. :asd:
EdgarVillier
08-04-2009, 19:50
Anzitutto, ringrazio tutti per le risposte, adesso però ho qualche altro quesito per chiarire :
link t = malloc(sizeof * t);
t è dichiarato come link, quindi l'espressione equivalente è:
link t = malloc(sizeof * link);
* link dereferenzia link, che è un puntatore e quindi restituisce struct node
quindi *link serve a deferenziare link ed a ottenere struct node.
La cosa che ancora non ho capito è perchè non è necessario fare il cast :
link t =(link) malloc(sizeof(node));
Grazie ancora
||ElChE||88
08-04-2009, 23:18
La cosa che ancora non ho capito è perchè non è necessario fare il cast :
link t =(link) malloc(sizeof(node));
Grazie ancora
In C per trasformare un void* (il tipo ritornato dalla malloc) in un qualsiasi altro puntatore non c'è bisogno del cast esplicito.
In C++ invece dovresti scriverlo.
EdgarVillier
09-04-2009, 02:13
Ok, perfetto grazie mille a tutti per avermi chiarito entrambi i dubbi. Anche se effettivamente la sintassi non è chiara adesso penso di aver capito meglio l'allocazione dinamica.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.