n° 219
Novembre 2017
Dicembre 13, 2017, 10:32:01 *
Benvenuto! Accedi o registrati.
Hai dimenticato l'e-mail di attivazione?

Accesso con nome utente, password e durata della sessione
Notizia:
 
   Indice   Linux Windows Techassistance Gameassistance videogame hardware Aiuto Ricerca Agenda Downloads Accedi Registrati  


* Messaggi recenti
Messaggi recenti
Pagine: [1] 2   Vai giù
  Stampa  
Autore Discussione: Accedere all'area di memoria di una struct puntata da Puntatore in altra Struct  (Letto 2887 volte)
0 utenti e 1 Utente non registrato stanno visualizzando questa discussione.
vuott
Newbie
*

Karma: +2/-1
Scollegato Scollegato

Messaggi: 31


Mostra profilo
« inserita:: Settembre 13, 2016, 12:19:43 »

Avendo due semplici Strutture, di cui una secondaria puntata da un membro di tipo Puntatore di altra Struttura principale:
Codice:
#include <stdio.h>
#include <stdlib.h>


struct Secondaria {
unsigned char uc;
short sh;
int in;
};


struct Principale {
short s;
struct Secondaria *se;
};


int main () {

int i;

struct Principale *pr = malloc(sizeof(struct Principale));
pr->s = 11;
pr->se = malloc(sizeof(struct Secondaria));

pr->se->uc = 194;
pr->se->sh = 44;
pr->se->in = 99;

for (i=0; i<16; i++)
printf("%d  =  %d\n", i, *((unsigned char *) pr + i) );

       free(pr->se);
       free(pr);

return (0);

}
nei valori mostrati dal ciclo "for", i quattro a cominciare dal byte numero d'indice 8, sono verosimilmente quelli afferenti al secondo membro di tipo Puntatore della Struttura "Principale", e che rappresentano l'indirizzo di memoria della Struttura secondaria puntata.

Vorrei sapere se è possibile accedere all'area di memoria della Struttura "Secondaria" dereferenziando quel membro Puntatore; e successivamente, quindi, leggerne i valori contenuti.
Registrato
oregon
Jr. Member
**

Karma: +22/-6
Scollegato Scollegato

Messaggi: 239


Mostra profilo
« Risposta #1 inserita:: Settembre 13, 2016, 08:29:03 »

Che vuoi dire esattamente con

dereferenziando quel membro Puntatore

?
Registrato
vuott
Newbie
*

Karma: +2/-1
Scollegato Scollegato

Messaggi: 31


Mostra profilo
« Risposta #2 inserita:: Settembre 13, 2016, 09:29:39 »

Nella sostanza io vorrei accedere all'area di memoria della Struttura secondaria tramite l'indirizzo di memoria, contenuto dal membro di tipo struct Secondaria *se; . Insomma utilizzarlo come una sorta di "porta" di/per quell'area.

...ovviamente, per conoscere i dati assegnati ai membri della Struttura Secondaria e la loro disposizione all'interno dell'area di memoria di questa Struttura, potrei agevolmente utilizzare questa istruzione:

printf("%d  =  %d\n", i, *((unsigned char *) pr->se + i) );

ma..., ripeto, vorrei semplicemente sapere se è possibile passare all'area di memoria di tale Struttura Secondaria agendo da quella Principale ed in particolare sul suo secondo membro (di tipo Puntatore).

Dunque partendo da un primo passo come il seguente:

   ...?... ((struct Secondaria *) pr + 8)
Registrato
oregon
Jr. Member
**

Karma: +22/-6
Scollegato Scollegato

Messaggi: 239


Mostra profilo
« Risposta #3 inserita:: Settembre 13, 2016, 09:57:21 »

Penso di aver compreso ma vorrei capire come mai l'indirizzo è a partire dall'offset 8

Compili a 64 bit? Particolari valori di packing impostati?

Qual è il sizeof(int) o di un puntatore?

short s è da due byte

xx xx

cosa c'è nei 6 byte prima dell'indirizzo?
Registrato
vuott
Newbie
*

Karma: +2/-1
Scollegato Scollegato

Messaggi: 31


Mostra profilo
« Risposta #4 inserita:: Settembre 13, 2016, 10:03:57 »

Compili a 64 bit? Particolari valori di packing impostati?
Compilo a 64bit.


Qual è il sizeof(int) o di un puntatore?
La quantità di memoria, dunque, occupata da un int con il mio sistema è pari a 4 byte, quella di un Puntatore risulta essere di 8 byte.


cosa c'è nei 6 byte prima dell'indirizzo?
Nei seguenti 6 byte dell'allineamento in memoria dopo i primi due dello short, ho solo e sempre valori pari a zero.

Ti riporto di seguito il risultato mostrato in Terminale:
0  =  11
1  =  0
2  =  0
3  =  0
4  =  0
5  =  0
6  =  0
7  =  0
8  =  48
9  =  112
10  =  165
11  =  1
12  =  0
13  =  0
14  =  0
15  =  0
Registrato
oregon
Jr. Member
**

Karma: +22/-6
Scollegato Scollegato

Messaggi: 239


Mostra profilo
« Risposta #5 inserita:: Settembre 13, 2016, 10:10:51 »

Il long int è da 8 byte?
Registrato
vuott
Newbie
*

Karma: +2/-1
Scollegato Scollegato

Messaggi: 31


Mostra profilo
« Risposta #6 inserita:: Settembre 13, 2016, 10:11:59 »

Il long int è da 8 byte?

Ho verificato che è di 8 byte.
Registrato
oregon
Jr. Member
**

Karma: +22/-6
Scollegato Scollegato

Messaggi: 239


Mostra profilo
« Risposta #7 inserita:: Settembre 13, 2016, 10:17:13 »

Allora qualcosa del genere, se non ho capito male

Codice:
struct Secondaria *ps = (struct Secondaria *)(*((unsigned long int *)((unsigned char *) pr + 8)));
printf("%d %d %d\n", ps->uc, ps->sh, ps->in);
Registrato
vuott
Newbie
*

Karma: +2/-1
Scollegato Scollegato

Messaggi: 31


Mostra profilo
« Risposta #8 inserita:: Settembre 13, 2016, 10:27:41 »

Allora qualcosa del genere....

Diciamo questo (vedi in particolare la riga dei printf):
Codice:
struct Secondaria *ps = (struct Secondaria *)(*((unsigned long int *)((unsigned char *) pr + 8)));
printf("%d\n", *((unsigned char*) ps));
        printf("%d\n", *((short*)ps + 1));
printf("%d\n", *((int*)ps + 1));

ed ancor più precisamente questo:
Codice:
for (i=0; i<8; i++)
printf("%d\n", *((unsigned char*)ps + i));


Ad ogni modo, bravo, mi hai risolto questo problema.

Grazie.
Registrato
oregon
Jr. Member
**

Karma: +22/-6
Scollegato Scollegato

Messaggi: 239


Mostra profilo
« Risposta #9 inserita:: Settembre 13, 2016, 10:40:44 »

Di nulla,

avendo il puntatore ps, l'uso che ne fai per accedere agli elementi della struttura è indifferente (puoi usare l'operatore -> o no ...).

Saluti
Registrato
vuott
Newbie
*

Karma: +2/-1
Scollegato Scollegato

Messaggi: 31


Mostra profilo
« Risposta #10 inserita:: Settembre 13, 2016, 10:40:49 »

Nei miei tentativi di risposta al mio problema avevo sostanzialmente intuito la tua medesima soluzione, ma non avevo, ahimé, compreso che fosse necessario quel preliminare cast: (unsigned char *) .
Ti volevo chiedere se me ne potevi spiegare - seppur brevemente - la sua imprescindibile funzione in questa questione da me sollevata.

Grazie.
Registrato
oregon
Jr. Member
**

Karma: +22/-6
Scollegato Scollegato

Messaggi: 239


Mostra profilo
« Risposta #11 inserita:: Settembre 13, 2016, 10:42:20 »

Ti riferisci a questo

(unsigned char *) pr + 8

?
Registrato
vuott
Newbie
*

Karma: +2/-1
Scollegato Scollegato

Messaggi: 31


Mostra profilo
« Risposta #12 inserita:: Settembre 13, 2016, 10:43:57 »

Ti riferisci a questo

(unsigned char *) pr + 8

?

Esattamente.

Se viene omesso, si riceve un errore "Segmentation fault".    Triste
Registrato
oregon
Jr. Member
**

Karma: +22/-6
Scollegato Scollegato

Messaggi: 239


Mostra profilo
« Risposta #13 inserita:: Settembre 13, 2016, 10:48:19 »

Per l'aritmetica dei puntatori, come sicuramente saprai. Se vuoi arrivare all'indirizzo base pr + 8 byte devi dire che il puntatore è di tipo byte altrimenti + 8 significa ben altro e chissà dove finisci.
Registrato
vuott
Newbie
*

Karma: +2/-1
Scollegato Scollegato

Messaggi: 31


Mostra profilo
« Risposta #14 inserita:: Settembre 13, 2016, 10:56:07 »

... devi dire che il puntatore è di tipo byte altrimenti + 8 significa ben altro e chissà dove finisci.
Ho capito.
uhmmmm... questa precisazione è una cosa da ricordare in futuro.
Molto bene.

Grazie ancora.
Registrato
Pagine: [1] 2   Vai su
  Stampa  
 
Vai a:  

Copyright © 2017 Edizioni Master SpA. p.iva : 02105820787

Tutti i diritti di proprietà letteraria e artistica riservati. - Privacy



powered by Simple Machines