PDA

View Full Version : [C] Problema con i puntatori e la connessa aritmetica


magix2003
20-09-2007, 10:05
Ciao a tutti,
mi sto leggendo il capitolo sui puntatori del K&R. Ho provato a compilare un esercizio, precisamente questo:

#define ALLOCSIZE 1000

static char allocbuf[ALLOCSIZE];
static char *allocp = allocbuf; /* puntatore al primo elemento dell'array */

char *alloc(int n) {
if (allocbuf + ALLOCSIZE - allocp >= n) { /* controlla se c'č sufficiente spazio */
allocp += n;
return allocp - n;
} else {
return 0;
}
}

void afree(char *p) {
if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
allocp = p;
}


Non č altro che un semplice allocatore di memoria. Dopodichč io ho cercato di scrivere un semplice "client" e qui sono sorti i primi problemi



#include "allocatore.h"
#include <stdio.h>

int main() {

char *tmp = alloc(5);
int i = (int) tmp + 5;
for (++tmp; tmp < i; ++tmp)
*(tmp++) = 'c';
*tmp = '\0';
printf("%s\n", *tmp);
return 0;
}


In questo modo non dovrei riuscire a scrivere all'interno dello spazio allocato? Quando cerco di stampare mi ritorna sempre NULL...
Grazie in anticipo

Giorgio

andbin
20-09-2007, 10:28
In questo modo non dovrei riuscire a scrivere all'interno dello spazio allocato? Quando cerco di stampare mi ritorna sempre NULL... Se richiedi 5 byte, allora puoi scrivere 4 caratteri pių un nullo finale. A parte che fare un cast a int di un puntatore non mi sembra la cosa pių bella e utile possibile.... comunque il loop non mi sembra nemmeno corretto (troppi incrementi!).

E in ogni caso alla fine vuoi stampare una stringa (%s) ma passi un carattere *tmp (ed č sbagliato) e in ogni caso il puntatore č ormai sul nullo finale.

trallallero
20-09-2007, 11:08
#include "allocatore.h"
#include <stdio.h>

int main() {

char *tmp = alloc(5);
int i = (int) tmp + 5;
for (++tmp; tmp < i; ++tmp)
*(tmp++) = 'c';
*tmp = '\0';
printf("%s\n", *tmp);
return 0;
}

perche´ chiami le funzioni alloc e free quando invece non fanno alloc e tantomeno free ?

perche´ per un semplice ciclo casti un char* ad int ?

capisco tu voglia sperimentare i brividi della dinamicita´ :D ma se il tutto si basa su un dato fisso (5)
a questo punto definiscilo ed usa la define ovunque ;)

Poi se usi questo ciclo:
for (++tmp; tmp < i; ++tmp)
ti giochi il primo elemento di tmp perche´ ++tmp e´ la prima istruzione che
viene eseguita.

*tmp = '\0';
qui sei fuori dal ciclo quindi l´ultima istruzione eseguita e´ stata ++tmp
il che significa che tmp punta a tmp+6, fuori dall´array, hai sforato.
Ti va bene (ma non sempre) e non crasha il programma ma se poi stampi
printf("%s\n", *tmp); e tmp e´ ´\0´ e´ facile che non ti stampi un accidente.

magix2003
20-09-2007, 11:30
Se richiedi 5 byte, allora puoi scrivere 4 caratteri pių un nullo finale. A parte che fare un cast a int di un puntatore non mi sembra la cosa pių bella e utile possibile.... comunque il loop non mi sembra nemmeno corretto (troppi incrementi!).

E in ogni caso alla fine vuoi stampare una stringa (%s) ma passi un carattere *tmp (ed č sbagliato) e in ogni caso il puntatore č ormai sul nullo finale.

Effettivamente ho fatto un po' di confusione, ma ho sempre avuto problemi con i pointers :mc:

Ora ho provato a modificare cosė il main:

#include "allocatore.h"
#include <stdio.h>

int main() {

char *tmp = alloc(5); //alloco 5 byte
char *p = tmp + 4; // fine del ciclo dopo 4 byte
char c = 'a';
for (tmp; tmp < p; tmp++)
*tmp = c++; // scrivo all'interno di tmp il carattere c
*tmp = '\0'; // al termine inserisco il carattere di chiusura
printf("%s\n", tmp); //dovrei stampare tutto a video
return 0;
}



Il problema č che non stampa a video, cioé mi stampa solo una riga vuota...

trallallero
20-09-2007, 12:00
Il problema č che non stampa a video, cioé mi stampa solo una riga vuota...

io ti ho scritto perche´

magix2003
20-09-2007, 12:16
io ti ho scritto perche´

Si, ma ora uso il puntatore tmp all'interno della printf, quindi si dovrebbe riferire a tutta la stringa. O?

trallallero
20-09-2007, 12:23
Si, ma ora uso il puntatore tmp all'interno della printf, quindi si dovrebbe riferire a tutta la stringa. O?

no, tu tmp lo incrementi:
for (tmp; tmp < p; tmp++)
significa che ad ogni giro del ciclo tmp punta all´indice successivo.

Alla fine del ciclo punta alla fine dell´array.
Infatti alla fine del ciclo tu setsso fai:
*tmp = '\0';

Di solito si usano scorritori in questi casi. NON puoi perderti l´inizio dell´array soprattutto se allocato dinamicamente, anche per poter poi liberare la memoria.

ti consiglio (cosi´ al volo) un:
char *array = alloc(5);
char *tmp = array;

// usi tmp per fare quello che fai e la printf diventa:
printf("%s\n", array);

71104
20-09-2007, 12:25
perche´ chiami le funzioni alloc e free quando invece non fanno alloc e tantomeno free ? ma dove la vedi la free? :wtf:

trallallero
20-09-2007, 12:28
ma dove la vedi la free? :wtf:

void afree(char *p) {
if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
allocp = p;
}
:read:

che poi e´ anche in romano, la dovresti vedere bene tu ... afree :asd:

71104
20-09-2007, 12:47
void afree(char *p) {
if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
allocp = p;
}
:read:

che poi e´ anche in romano, la dovresti vedere bene tu ... afree :asd:

AAAAAA ECCO, afree, volevo ben dire :O

magix2003
20-09-2007, 13:03
Grazie mille,
sono proprio rintronato oggi..

Ciauz