2016-01-04 8 views
5

Sto cercando di capire i puntatori e mi sono imbattuto in questo pezzo di codice e ogni volta che lo compilo ed eseguo, l'indirizzo cambia. È un po 'di valore spazzatura o puntatori ottengono effettivamente la memoria assegnata in movimento?Gli indirizzi dei puntatori cambiano ogni volta che il programma viene eseguito in C?

mio prompt dei comandi:

[email protected]:~/Desktop/Learn_C$ ./Practice 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0xbf98fd64 

[email protected]:~/Desktop/Learn_C$ make Practice 
make: 'Practice' is up to date. 

[email protected]:~/Desktop/Learn_C$ ./Practice 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0xbfcce2a4 

[email protected]:~/Desktop/Learn_C$ ./Practice 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0xbfa25df4 

[email protected]:~/Desktop/Learn_C$ ./Practice 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0xbfecf104 

Il mio codice C è:

#include <stdio.h> 

int main() 
{ 
    int nNumber; 
    int *pPointer; 

    nNumber = 15; 
    pPointer = &nNumber; 

    printf("nNUmber is equal to : %d\n", nNumber); 

    *pPointer = 25; 

    printf("nNumber is equal to : %d\n", nNumber); 

    printf("%p\n", pPointer); 

    return 0; 
} 

Grazie in anticipo.

+4

È una funzionalità di sicurezza in generale: [Indirizzo randomizzazione della disposizione dello spazio] (https://en.wikipedia.org/wiki/Address_space_layout_randomization) –

+1

Perché il downvote. Questa è una domanda legittima. – alk

risposta

4

La rappresentazione o cosa costituisce esattamente un valore puntatore è un dettaglio di implementazione. Lo standard C non indica alcun requisito su di esso. Non è possibile garantire se il valore sarà uguale o diverso ogni volta che si esegue il codice.

Solo l'aritmetica del puntatore tra i puntatori validi (ad esempio il confronto di due puntatori all'interno di un oggetto matrice) è definita dallo standard C.

A proposito, si dovrebbe lanciare il puntatore void* da stampare con %p come richiesto dallo standard C:

printf("%p\n", (void*) pPointer); 

Come notato nei commenti, alcuni sistemi operativi fanno address space layout randamization. Linux lo fa per impostazione predefinita. Per il vostro codice, ottengo il seguente output con ASLR:

$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffde18ba7c 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fff981efe0c 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7ffdade6837c 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7ffced208b4c 

Se rendo invalido con:

echo 0 > /proc/sys/kernel/randomize_va_space 

allora emette gli stessi valori:

$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 

Ma per quanto riguarda Lo standard C è preoccupato, non c'è assolutamente alcuna garanzia sui valori.

1

È qualche valore indesiderato o puntatori ottengono effettivamente la memoria assegnata in movimento?

Nessuno dei due. Il valore del puntatore che si sta stampando è diverso perché l'indirizzo dell'oggetto puntato (nNumber) è diverso per ogni esecuzione del programma o perché lo stile di rappresentazione puntatore in uso offre rappresentazioni differenti per lo stesso indirizzo o entrambi. In pratica, il primo è molto più probabile.

L'indirizzo di nNumber è una funzione di dove il programma viene caricato nella memoria (virtuale) e nulla richiede che sia coerente da esecuzione a esecuzione. Infatti, come osserva Jeff Mercado nei commenti, esiste un meccanismo chiamato "Randomizzazione dello spazio degli indirizzi" che, laddove impiegato, randomizza intenzionalmente indirizzi di carico del programma e della libreria al fine di migliorare la sicurezza del sistema. Il suo uso è una spiegazione plausibile e abbastanza probabile per la tua osservazione, ma non è affatto l'unica possibile.

Problemi correlati