
Originariamente inviata da
BoG
Ciao a tutti, ho una domanda da fare:
Dato il codice:
codice:
using namespace std;
#include <iostream>
void cambia(int m, int n[7]){
for(int i=0;i<7;i++)
cout << "n["<<i<<"]: " << n[i] <<endl;
(*(n+m))--;
m++;
n--;
}
int main(){
int vet[] ={4,2,3,2,4};
cambia(vet[4], vet-1);
cambia(0,&vet[4]);
int i=0;
for(i=0; i<5; i++)
cout << vet[i];
return 0;
}
faccendolo eseguire, noto che
..?? non dovrebbe esserci memoria sporca?
Tanto per darvi un idea: eseguendo il codice ho l'output:
codice:
bog@bog-desktop:~$ ./a.out n[0]: 0
n[1]: 4
n[2]: 2
n[3]: 3
n[4]: 2
n[5]: 4
n[6]: 32767
n[0]: 4
n[1]: 32767
n[2]: 0
n[3]: 0
n[4]: 0
n[5]: 0
n[6]: -1924407835
42313
Dove dici vet[-1]? Non c'è nessun accesso alla locazione -1, ed un accesso simile provocherebbe sicuramente un errore di compilazione. Quel "vet-1" passa praticamente un indirizzo di memoria (quello di vet) sottraendo però -1.
Ad esempio l'indirizzo di vet è: 0x28fef8
Se passo vet-1 ottengo: 0x28fef4
Se passo vet+1 ottengo: 0x28fefc
Il primo valore che viene stampato è causato proprio da questo infatti.
Poi vorrei fare un altra domanda:
come potete vedere, nell'esercizio, passo un vettore di dimensione 5 ad un vettore di dimensione 7. Ok, immagino che compilera' i 5 campi con i valori passatigli e gli altri rimaranno memoria sporca. Ma se io passassi il mio vettore di 5 elementi ad uno di 2? i primi 2 come funzionerebbe?
In realta', io so che vet[] non è altro che un puntatore al primo elemento dei valori inseritivi. quindi ... che io passi il mio vettore di 5 elementi ad un vettore di 10 o solo 1 ... non fa differenza, no ?
se io so che dentro ci sono 5 elementi, io posso scrivere vettore[5] anche se il vettre è stato dichiarato ti dimensione 1. Giusto?
GRazie a tutti
Il problema è che rischi (anzi, non è un rischio, è una certezza) di sovrascrivere altro in memoria. Se tu hai memoria per 2 elementi e gli vai a passare l'indirizzo di un array con 5, tu puoi accedere tramite quell'array agli elementi di quello con 5 (avendo lo stesso indirizzo). Ma prima avevi riservato due posti in memoria, quindi rischi di andare a sovrascrivere i dati che ci sono dopo ai due elementi allocati con 3 aggiuntivi quindi.
E' un riscontro che puoi avere anche sul tuo codice quello riguardante gli accessi:
codice:
using namespace std;
#include <iostream>
void cambia(int m, int n[2]){
for(int i=0;i<5;i++)
cout << "n["<<i<<"]: " << n[i] <<endl;
cout << "Indirizzo n "<< n;
}
int main(){
int vet[] ={4,2,3,2,4};
cambia(vet[4], vet);
cout << "\nIndirizzo vet: "<<vet;
return 0;
}
Output:
codice:
n[0]: 4
n[1]: 2
n[2]: 3
n[3]: 2
n[4]: 4
Indirizzo n 0x28fefc
Indirizzo vet: 0x28fefc
Quindi di fatto sullo stack la differenza c'è...
Ad ogni modo non mi sembra una pratica "necessaria" questa.
PS: non so se mi sono espresso correttamente, al massimo riformulo.