2013-05-12 26 views
5

Programma:Puntatori e allocazione della memoria in C

int x; 
int *y; 
int **z; 

z = (int **) malloc (sizeof(int *)); 
y = (int *) malloc (sizeof(int)); 
x = 1; 
*z = &x; 
*y = x; 
. 
. 
. 

Domanda: Qual è la differenza tra:

*z = &x; 
*y = x; 

Da quello che ho capito * z indica l'indirizzo di x e * punti y a x, ma per * y puntare a x non richiede l'indirizzo di x? Non capisco veramente cosa stia succedendo con queste due variabili.

Modifica: Voglio anche sapere quando sappiamo quando una variabile è allocata nello stack o nell'heap?

  • Perché x, ye z sono allocati nello stack?
  • Perché * y, ** y, * z, ** z, allocati nell'heap?

Infine, cambia * z, cambia ** z?

+0

"Da quello che ho capito ..." Hai frainteso. z e y puntano ancora a qualsiasi blocco di memoria a cui hanno indicato quando li hai assegnati. –

+0

Non si dovrebbe eseguire il cast del valore di ritorno di 'malloc()' in C. Ciò aiuterà a identificare il bug di non avere un prototipo per questo. – jxh

+1

Prima di tutto è necessario capire che queste ultime due dichiarazioni sono completamente diverse. Il primo assegna * l'indirizzo * di x a qualsiasi punto z, mentre il secondo assegna il * valore * di x a qualunque cosa y punti. Se assegni un valore, l'originale e la copia diventano "disconnessi" in modo che cambiandone uno non cambi l'altro. Ma quando si usa solo l'indirizzo, i due si uniscono al fianco, cambiandone uno e si cambia l'altro. –

risposta

6

z è un puntatore a un puntatore (che in genere punta a una matrice allocata dinamicamente di puntatori).

è un puntatore a int. Ancora una volta, il più delle volte punta ad una matrice allocata dinamicamente di int s.

Quindi, il *z = &x; sta impostando il puntatore a z per indicare a x. I.e., z punti a un puntatore, che (a sua volta) punta a x.

*y = x; sta prendendo il valoredi x e assegnando al int puntata da y.

Per cose come questa, un'immagine è spesso utile.Quindi, le nostre definizioni di base ci danno questa:

enter image description here

Il facciamo:

z = (int **) malloc (sizeof(int *)); 
y = (int *) malloc (sizeof(int)); 

Il che ci dà questa:

enter image description here

Poi facciamo:

*z = &x; 
*y = x; 

Il che ci dà questa:

enter image description here

In tutti questi, una linea tratteggiata significa un puntatore da un luogo ad un altro, mentre la linea continua indica la copia di un valore da un luogo all'altro.

Possiamo quindi considerare le differenze a lungo termine tra di loro. Ad esempio, considera cosa succede se aggiungiamo x=2; dopo tutti i compiti sopra indicati.

In questo caso, *y sarà ancora uguale 1, poiché abbiamo copiato il valore 1 da x a *y. **z sarà uguale a 2, perché è solo un puntatore a x - qualsiasi modifica di si rifletterà in **z.

2

Questa linea memorizza l'indirizzo di variabile x nella memoria puntato da z:

*z = &x; 

Questa linea memorizza il valore di x nella memoria puntata da y:

*y = x; 

Le due dichiarazioni di assegnazione non sono correlate: la seconda fa una copia, il primo non lo fa. Se si modifica il valore di x e quindi si recupera **z, verrà visualizzato il nuovo valore x; tuttavia, il recupero di *y restituirà il vecchio valore di x (ad esempio 1).

+0

Grazie! Questo ha molto senso! –

0

la differenza tra i due assegnazioni è che il primo (* z) è un'assegnazione di un tipo di indirizzo come il valore del puntatore, in cui la seconda (* y) è un'assegnazione di valore a un indirizzo indicò di y.

entrambi assegnano valori a una memoria a cui sono puntati.

la differenza è il tipo di valore scritto nella memoria allocata. il primo valore è un indirizzo ed è per questo che ottiene l'indirizzo di x come valore. il secondo valore è un numero intero e lì per esso ottiene il valore di x.

* y non punta a x.

punta a una posizione di memoria sconosciuta in cui viene copiato il valore di x. è un'assegnazione del valore di x allo spazio di memoria allocato per y.

Problemi correlati