Newsgroup: it.comp.lang.c++
Titolo: problema banale

ho allocato uno spazio di memoria di svariati megabytes con
dataPtr = new unsigned char[filesize];
il problema che non riesco a risolvere è questo:
come posso accedere a questi dati se il linguaggio
non mi permette di sommare un puntatore a carattere
con una variabile di tipo Long o anche Int??
es:
posiz = dataPtr;
posiz = (unsigned char)HEADERSIZE + (distanza * x)+y;
dove distanza necessariamente è di tipo Long
mentre x ed y sono tipo unsigned char
spero non mi tocchi fare un ciclo for per calcolare il valore
mediante incremento, sarebbe un orrore...
ciao
Paolo

 
??? Mah...
-- 
Roal Zanazzi

 posiz = HEADERSIZE + (distanza * (long)x) + (long)y;
ora provo


semplificando un po le cose:
dataPtr = new unsigned char[filesize];
 dataPtr e' 1 puntatore a dati "unsigned char" che punta all'inizio dell'area allocata
posiz=dataPtr
  posiz è sempre 1 puntatore come dataPtr e punta allo stesso indirizzo di memoria
a me serve posizionarmi con il puntatore su un certo punto dei dati allocati con un
offset ed ho pensato di scrivere:
posiz += offset;
  dove offset deve essere per forza di tipo "int"
ma il compilatore mi dice che non posso perche' offset e' di tipo "int"

S¥0 ha scritto in it.comp.lang.c++:

Se non è segreto miltare posta la parte di codice incriminata.
E magari anche le definizioni delle variabili che usi.
Oppure ancora meglio un piccolo programma di test che metta in
evidenza il problema, e magari realizzando questo riesci anche
a trovare il problema da solo.

 
Posta il testo dell'errore (o e' un warning?).
E magari dicci anche che compilatore stai usando.
-- 
Roal Zanazzi

 a trovare il problema da solo.
ho trovato il problema:
ad un puntatore posso aggiungere una variabile di tipo int ma non di tipo long
tutto qua'. Ho risolto cambiando il tipo di variabile
grazie e ciao.

 posiz += offset;
In realta', per essere precisi precisi dovresti scrivere
std::ptrdiff_t offset = 100;
posiz += offset;
L'offset e' un tipo col segno, altrimenti come fai a tornare indietro?
Ciao,
Nicola

 
Hai perfettamente ragione, ho scritto un po' di fretta.
-- 
Roal Zanazzi

S¥0 ha scritto:

Mi sembra una ca**ata.
Ci vuoi svelare quale compilatore stai usando e qual e' il messaggio 
COMPLETO dell'errore che ti da?
-- 
Roal Zanazzi

 grazie e ciao.
stai pazziando?
    MLO@mlinux 4 $ cat foo.cxx
    int main() {
      unsigned char * pc1 = new unsigned char[100];
      long offset = 10;
      unsigned char * pc2 = pc1;
      pc2 += offset;
      delete [] pc1;
    }
    MLO@mlinux 5 $ g++ -std=c++98 -pedantic -W -Wall -o foo foo.cxx && ./foo
    MLO@mlinux 6 $ 
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy              ROT13: 
ybe...@cq.vasa.vg

 L'offset e' un tipo col segno, altrimenti come fai a tornare indietro?
Usi la sottrazione ;)
Kiuhnm

  dataPtr e' 1 puntatore a dati "unsigned char" che punta all'inizio dell'area allocata
Presumo che prendi la dimensione di un file (filesize), allochi tanti
byte quanto il file è grande, ne copi il contenuto la dentro, e poi ti
ci muovi con i puntatori.
Consiglio di fare una mmap() di quel file, meglio con boost::iostreams
che è windows/posix.
In pratica, su un file aperto, usi i puntatori invece degli offset
senza allocare un buffer.
Saluti,
alef

 tutto qua'. 
rimane tutto piuttosto strano. Dovrebbe darti un warning e non 
segnalarti errore, in quanto il downcast da long a int è 
fattibile anche in automatico (con warn). Su molte macchine anzi 
il layout di int è uguale a long (e non più a short, come 
qualche annetto fa).
Il possibile overflow del buffer dovrebbe essere un classico 
errore di runtime, e non di compile time.
Mi viene un altro dubbio ... stai compilando con opzioni 
particolari sul MODELLO di memoria dell'eseguibile (es. tiny, 
con codice + dati + stack in un unico segmento di 64 KB, o altri 
modelli con puntatori "corti" ?).
Ciao
Soviet


 a trovare il problema da solo.
ecco qua: essendo un po' lungo ho duvuto estrarre la parte che mi dava problemi:
non sara' il massimo come codice ma sono i primi esperimenti che sto facendo.
perdonatemi...
Ora me lo compila regolarmente: uso VC++6
grazie
#define HEADERSIZE "0x36"
void main()
{
unsigned long filesize;
unsigned long width;
unsigned long height;
unsigned long imagesize;
unsigned long distanza;
unsigned long offset;
unsigned int lunghPayload;
unsigned long distanza;
unsigned char b;
unsigned char bit[8];
unsigned char * posiz, * pos;
unsigned char binand[]= {1,2,4,8,16,32,64,128};
unsigned int x,y,z,bit1;
char payload[200000];
ifstream fin2(FILEBMP,ios::binary);
if (!(fin2.rdstate()==0)) {
segnalaerrore(CANTOPENFILEINPUT,FILEBMP);
exit(0); }
[...]
//legge l'header del file
//ed imposta le variabili "filesize", "imagesize" e "lunghPayload"
[...]
unsigned char * dataPtr;
dataPtr = new unsigned char[filesize+1];
if (dataPtr == NULL ) {
segnalaerrore(NOMEMORY,"");
exit(0); }
pos=dataPtr;
for (x=0; x< filesize; x++) {
    fin2 >> colore;
    *pos=colore;
    pos++; }
fin2.close();
distanza = imagesize / (lunghPayload + 1);
for (x=0; x < lunghPayload; x++) {
    for ( y=0; y<8; y++ ) {
        b = payload[x] & binand[y];
        if (b==binand[y])
        bit[7-y]=1;
        else
        bit[7-y]=0; }
    posiz = dataPtr;
    posiz += (unsigned char)HEADERSIZE + (distanza * x) + y;   // questa era la riga incriminata
    for (z=0; z<8; z++, posiz++) {
        bit1 = *posiz & 1; // leva i primi 7 bit
        if (bit1 != bit[z]) *posiz ^= 1;   }
}
} 

 ha scritto nel messaggio

ma perchè definisci HEADERSIZE come stringa ?
se è la dimesione dell'header da sommare dovrebbe essere di tipo intero
#define HEDAERSIZE 0x36
o meglio:
const size_t HEADERSIZE = 0x36;
a questo punto la linea incriminata diventa:
posiz += HEADERSIZE + (distanza * x) + y;
e fila tutto liscio