2013-05-15 6 views
8

ho creato un semplice programma:Dichiarazione delle variabili ed i loro indirizzi di memoria in C

#include <stdio.h> 

int main() 
{ 
    int s1; 
    int s2; 
    int s3; 

    int *p1, *p2, *p3; 

    p1 = &s1; 
    p2 = &s2; 
    p3 = &s3; 

    printf("%d\n%d\n%d", p1, p2, p3); 
} 

Ogni volta che esegue questo programma, esso stampa gli indirizzi di memoria di puntatori p1, p2 e p3 e la cosa interessante è che questi valori avere differenze di 12. Voglio sapere la ragione di questo. Perché gli indirizzi differiscono da 12?

Nota: questo succede ogni volta Eseguo il programma.

uscita:

enter image description here


ho provato lo stesso programma in molti tipi di variabili, i risultati che ottiene sono ..

Quando le variabili sono di tipo char. enter image description here


Quando le variabili sono tipo lungo enter image description here


Quando dichiaro int matrice, dimensioni ogni matrice è 1. enter image description here


Quando dimensione della seconda matrice dichiarata è 2, ottiene un offset extra di 4 byte. enter image description here

+1

Perché non utilizzare l'identificatore di formato progettato per i puntatori di stampa o, meglio ancora, 'std :: cout'? E perché non usare una firma valida per 'main'? – chris

+0

Uno sguardo al codice generato (in un debugger o un disassemblatore) probabilmente ti aiuterà a illuminarti. – cHao

+6

Che cosa sono il compilatore e la piattaforma? – Steve

risposta

5

Sono abbastanza sicuro che si tratta di un caso in cui "il compilatore inserisce elementi aggiuntivi per rilevare quando si scrive in posti che non si dovrebbero". A Micrsoft piace farlo, in modo che possa rilevare quando il codice sta facendo cose cattive. Provare qualcosa di simile:

void func() 
{ 
    int x = 18; 
    int *px = &x; 
    px[1] = 4711; 
    cout << "px = " << px << " x = " << x << " px[1] = " << px[1] << endl; 
} 

e vedere se il compilatore non "rileva" che questo codice sta facendo cose cattive ... Se lo fa, è perché è messo "padding" tra X e ep, e controlla quando la funzione restituisce che quelle aree "padding" non sono state toccate.

+0

'gcc -g -O0 -Wall -fstack-protector-all -Wstack-protector op_code.c -o a.out' fornisce offset di 4 byte quale protezione ha Windows che gcc non ha ?? – 0x90

+0

@ 0x90 (o dovrei chiamarti NOP?): Uno dei commenti dice che l'OP sta usando Visual Studio 2008, quindi non usare gcc. –

+0

So che è per questo che chiedo che cosa il compilatore di Microsoft sa fare con GCC no? :) – 0x90

15

Suppongo che si tratti di una build di debug. Ho provato questo programma creato con Visual Studio 2010. Sul debug c'è una differenza di 12 byte tra gli indirizzi. Nella modalità di rilascio è presente una differenza di 4 byte (sizeof(int)).

Nelle compilazioni di debug il compilatore MSVC aggiunge dati aggiuntivi per aiutare a rilevare i buffer overflow e l'uso di memoria non inizializzata. Se si imposta un punto di interruzione sull'istruzione printf e si visualizza la memoria indicata da p1, si dovrebbe vedere cc nella memoria.

Ci sono diversi valori magici a cui è stata inizializzata la memoria. cccccccc indica lo spazio di stack non inizializzato. Per un elenco più dettagliato, vedere la risposta a questa domanda: In Visual Studio C++, what are the memory allocation representations?

Problemi correlati