Newsgroup: it.comp.lang.c
Titolo: cambiare gli elementi da int a void*??

Ciao a tutti,ho questa struttura dati e devo cambiare gli elementi (elements 
nella struct_pila)da int a void *,ma non so' assolutamente come fare,qualche 
anima pia,mi puo' aiutare?
struct struct_pila
{
 int* elements; //contiene gli elementi della pila
 int next; //indica dove inserire il prossimo elemento
 int capacity; //lunghezza dell'array elements
};
PilaI nuovaPila(int capacity)
{
 if (capacity <= 0) exit(-1);
 PilaI s = (PilaI) malloc (sizeof (struct struct_pila));
 s->elements = (int*) malloc ((sizeof(int)) * capacity);
 s->capacity = capacity;
 s->next=0;
 return s;
}
int isEmpty(PilaI s)
{
    if(s->next==0) return 1;
    else return 0;
}
PilaI push(PilaI s, int e)
{
    if(s->next >= s->capacity) exit(-1);
    PilaI n = (PilaI) malloc (sizeof (struct struct_pila));
    n->elements = (int*) malloc ((sizeof(int)) * s->capacity);
    n=s;
    n->elements[n->next]=e;
    n->next++;
    return n;
} 

 anima pia,mi puo' aiutare?
Inanzitutto, li vuoi cambiare da int* a void*, al massimo, non da int a 
void*. Poi: *perche'*? Detta cosi', quello che vuoi fare e' banale: 
cambi "int*" in "void*" nella dichiarazione. Ti trovi un programma che 
non compila, ma questo e' quello che hai chiesto, quindi... insomma, 
come sempre: quando si fa una domanda, si deve pensare se e' 
comprensibile facilmente a chi la riceve! :P
Altra nota da quello che vedo, velocemente: non conviene mai fare cast 
sul valore di ritorno di malloc. Se vuoi sapere il perche', dai 
un'occhiata alle FAQ del gruppo.
Infine, il codice che hai postato e' incompleto (ad es.: "PilaI" cosa 
sarebbe?)
-- 
Mat/tia Belletti - Undergraduate student @ 
cs.unibo.it
ICQ: 33292311    - email: 
mbel...@cs.unibo.it
IRC: RedGlow     - site(s): 
http://mbellett.web.cs.unibo.it/
Jabber: RedGlow  - Linux registered user 299762 @ machine 213003

 void*.
Sempre che non si tratti di codice "archeologico" in cui i puntatori
considerati "generici" venivano memorizzati in interi... :-)
C:\>iao Angelo
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 mi puo' aiutare?
Se ho capito bene quello che vorresti fare, sotto trovi un codice che fa
quello che ti serve; solo alcune note al codice che hai postato:
Lo spazio che ti occorre per la pila lo allochi gia`, giustamente, quando
la crei; perche`, allora, nella funzione push allochi ancora una nuova
pila e non liberi quella vecchia? Questo e` un errore e provoca memory
leaks. Senza contare che tu avresti bisogno di sole 2 allocazioni nel tuo
programma (struct_pila e array elements), mentre cosi` facendo eseguiresti
al piu` 2capacity+2 allocazioni (nel caso la pushassi tutta). Se, quindi,
indichiamo con x la dimensione di struct_pila, con y la dimensione di un
singolo elemento e con z la capacita` della pila, si evince che tu
allocheresti, nel caso peggiore appunto, x(z+1)+zy(z+1) bytes invece dei
x+zy che ti occorrono, sprecando cosi` zx+z^2y bytes e facendo 2z
allocazioni in piu`.
Sempre nella funzione push, posto che la struct struct_pila di appoggio
non serve, non ti conviene neanche ritornare un puntatore alla medesima,
in quanto o non saresti in grado di capire una condizione di errore (pila
full) oppure, se decidessi di segnalare questa eventualita` con un
puntatore nullo, perderesti la referenza al vecchio ottenendo ancora un
memory leak; potresti risolvere con un puntatore esterno temporaneo stile
realloc ma, essendo, in questo caso, veramente inutile (puoi
tranquillamente modificare il contenuto della struct senza necessariamente
ritornarla), ti conviene ritornare un intero.
In nuovaPila controlli che capacity sia minore o uguale a 0; essendo che
l'insieme di riferimento degli interi e` N, sarebbe sufficiente
controllare che capacity non sia strettamente minore di 1.
Questione di gusti personali, invece, la stessa faccenda nella funzione
push; io preferisco eseguire sempre il controllo "piu` piccolo", quindi,
anche qui, preferisco testare la condizione di minoranza stretta.
Infine la funzione isEmpty e` talmente banale che, personalmente, la
riscriverei sotto forma di macro.
Ecco il codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef ELEMENTS_TYPE
# define ELEMENTS_TYPE   int
#endif
#ifndef FORMAT_STRING
# define FORMAT_STRING   "%d "
#endif
#ifndef MAX_NUM_ITEMS
# define MAX_NUM_ITEMS   20
#endif
#define isEmpty(x)      ((x->next == 0) ? 1 : 0)
#define nuovaPila(x)    __nuovaPila(x, sizeof(ELEMENTS_TYPE))
#define push(x,y)       __push(x,y,sizeof(ELEMENTS_TYPE))
#define print(x)        __print(x, FORMAT_STRING, ELEMENTS_TYPE)
#define __print(x,y,z) \
do \
{ \
  int i; \
  \
  for (i = 0; i < x->next; i++) \
    (void)fprintf(stdout, y, *((z *)x->elements + i)); \
  \
  puts(""); \
} \
while(0);
struct struct_pila
{
  void *elements; /* contiene gli elementi della pila */
  int next; /* indica dove inserire il prossimo elemento */
  int capacity; /* lunghezza dell'array elements */
};
typedef struct struct_pila *PilaI;
PilaI __nuovaPila(int capacity, size_t s_item)
{
  PilaI s = NULL;
 
  if (capacity < 1)
    return NULL;
 
  if ((s = malloc (sizeof (struct struct_pila))) == NULL)
    return NULL;
 
  if ((s->elements = malloc (s_item * capacity)) == NULL)
  {
    free(s);
    return NULL;
  }
 
  s->capacity = capacity;
  s->next = 0;  
  return s;
}
int __push(PilaI s, void *e, size_t s_item)
{
  if (s->next < s->capacity)
  {
    (void)memcpy(s->elements + s->next++ * s_item, e, s_item);
    return 1;
  }
 
  return 0;
} 
int main(void)
{
  PilaI p = NULL;
  int i;
 
  if ((p = nuovaPila(MAX_NUM_ITEMS)) == NULL)
    exit(1);
 
  for (i = 0; i < MAX_NUM_ITEMS; i++)
    if (!push(p, &i))
      break;
 
  print(p);
 
  free(p->elements);
  free(p);
  return 0;
}
Cambiando solo le prime 3 define sei in grado, col medesimo codice, di
creare pile di numero elementi e tipo desideri.
Ciao
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 considerati "generici" venivano memorizzati in interi... :-)
<Brivido> 8-)


 <Brivido> 8-)
scusate se mi intrometto... ma per esempio questa cosa serve per la
funzione 
int pthread_create (pthread_t * THREAD, pthread_attr_t * ATTR, void *
(*START_ROUTINE)(void *), void * ARG)
, dove l'argomento, come si puň vedere, DEVE essere void *, cosě come il
tipo di ritorno della funzione eseguita dal thread posix... quindi io per
usarla devo fare un casting nel modo che state denigrando!! 
(ho degli esempi, da manuale, in cui un socket (che č visto come un intero)
č passato al thread solo per mezzo di un casting (void *)&socket )
--
saludos @lessio
===================================================
"  quando c'era lui i treni partivano in orario
   quando c'era lui ci deportavano in orario 
   quando c'era lui non c'eravamo noi
   che se c'eravamo noi 
           saremmo stati impallinati  " (caparezza)
===================================================

 č passato al thread solo per mezzo di un casting (void *)&socket )
E infatti non era questo che criticavamo.
