PDA

Visualizza la versione completa : [C] problema con malloc


Dimitree88
03-02-2012, 18:00
ciao a tutti
ho dei problemi con l'allocazione di risorse.
ecco il codice.
molte cose non hanno senso nè utilità, poichè è soltanto un esecizio.
l'ultima istruzione, la printf, mi stampa una stringa di 4 caratteri, e anche il campo size contiene 4. Dunque immagino che sto allocando spazio sufficiente per un semplice puntatore e non per i dati.



typedef struct {
void *campo;
size_t size;
} mystruct;




// crea una nuova struttura
mystruct nuova;

// crea un buffer di dimensioni stabilite (dovrei controllare il risultato di malloc..)
void *buffer = malloc(500*sizeof(char));

// copia i dati nel buffer (non ha senso ma è solo una prova, verrà sostituita da una funzione di lettura su stdin)
strncpy(buffer, "prova prova prova prova", sizeof(&buffer));

// alloca per il puntatore void di mystruct abbastanza spazio (che ora è noto) per contenere i dati del buffer
nuova.campo = malloc(strlen(buffer));
if(nuova.campo == NULL)
return -1;

// copia quindi i dati dal buffer al puntatore
strncpy(nuova.campo, buffer, strlen(buffer));

// copia la dimensione del messaggio nel campo apposito
nuova.size = strlen(buffer);

//qua dovrei rilasciare la memoria di buffer

// verifica
printf("%s %d", (char*)nuova.buf, nuova.size);


inoltre mi chiedevo se come principio è giusto quello di allocare dinamicamente la variabile buffer, poichè questo pezzo di codice dovrei usarlo spesso. Un alternativa sarebbe sovrascrivere di continuo il buffer, stavolta allocato staticamente. Quale delle 2 è meglio secondo voi?
mi scuso per l'evidente ignoranza in materia

ramy89
03-02-2012, 19:09
Invece di usare la strncpy passandogli come terzo argomento a lunghezza della stringa, puoi usare la strcpy (che ha 2 argomenti).
Poi non capisco cos'è nuova.buf, forse intendevi nuova.campo?
Per quanto riguarda l' allocazione, ti conviene si tenere un' area di memoria nello stack e sovrascrivere la stringa ogni volta, se la stringa ha N caratteri puoi limitare il numero di caratteri che verranno letti con fgets:


char buffer[N];
fgets(buffer,N,stdin); // prendi in input la stringa, consideri al massimo N caratteri


Un' altra cosa che hai sbagliato:


strncpy(buffer, "prova prova prova prova", sizeof(&buffer));

Forse intendevi sizeof(buffer), non sizeof(&buffer), ma era comunque sbagliato.
Ti stampa 4 caratteri perchè hai una macchina a 32 bit e &buffer è l' indirizzo di buffer.Nelle macchine a 32 bit un indirizzo è lungo 4 byte, per cui ti copia solo i primi 4.
Anche se avessi scritto sizeof(buffer) te ne avrebbe copiati 4, perchè buffer è un puntatore.
Se invece hai un array:


char buffer[100];
printf("%d\n",sizeof(buffer));

Ti stampa 100 perchè buffer è nello stack e non nell' heap.
Nel tuo caso avresti dovuto usare strcpy, o passare come parametro strlen alla strncpy.

Dimitree88
03-02-2012, 19:48
ti ringrazio, con queste correzioni è perfetto.

Allora a questo punto tolgo anche l'allocazione dinamica.

Dimitree88
04-02-2012, 16:17
nel momento in cui dovessi passare uno struct* a una funzione, non c'è proprio modo di sapere quant'è la grandezza effettiva di tale struct, se non quello di chiedere a sizeof(struct)?
mi spiego meglio:

struct prova {
char *a;
char *b;
}

struct prova nuova;

non essendo definita la dimensione di "prova", la dimensione di "nuova" potrebbe variare a seconda delle allocazioni che le si fanno durante l'esecuzione, giusto?
quindi,

scrivi_su_file(&nuova);

all'interno di questa funzione, nuova è visto come un puntatore, ma come faccio a conoscere le dimensioni effettive? devo passare alla funzione anche le dimensioni? il sizeof(nuova) al suo interno chiaramente mi restituisce la dimensione di un puntatore.

oregon
04-02-2012, 16:28
Non ho capito bene cosa intendi ...

La grandezza della struttura è 8 perché composta da due puntatori (che si suppone siano a 32 bit).

Cosa ti occorre sapere?

ramy89
04-02-2012, 16:38
Un puntatore ha dimensione costante, non importa quanta memoria ci allochi.
Per cui la dimensione sarà sempre la stessa anche se in prova.b ci allochi 1000 char.
Comunque la sintassi è:



sizeof(struct prova)

Dimitree88
04-02-2012, 16:56
ah cavolo, è vero, che stupido!
vi ringrazio per l'aiuto!

Loading