Sizeof(pipe_t): numeri di byte necessary per allocare UN oggetto di tipo pipe_t in memoria (per la precisione, nello heap)
N*sizeof(pipe_t): numeri di byte necessari per allocare N oggetti di tipo pipe_t
A questo punto:
malloc(N*sizeof(pipe_t))
ritorna un puntatore generico (void *) ad un blocco di memoria (allocato nello heap) in grado di tenere un vettore di N oggetti di tipo pipe_t.
Quindi:
(pipe_t *)malloc(N*sizeof(pipe_t))
dice che il puntatore NON E ' puntatore generico, ma un puntatore ad un vettore di N oggetti di tipo pipe_t
Dove pipe_t e' il tipo di pipe
A parte la battuta, un modo alternativo per allocare un vettore di N elementi di tipo pipe_t e':
(pipe_t *)calloc(N, sizeof(pipe_t))
invece di malloc, si usa la calloc.
La differenza e' minima: la parte interessante e' che la calloc inizializza il blocco di memoria a 0, mentre la malloc non fa nessuna inizializzazione (quindi leggermente piu' veloce, ma solo mooolto leggermente)