Ok je vais te faire une explication plus détaillée.
Voici une fonction main toute simple:
int main()
{
int *i = NULL;
alloc(i);
*i = 1
return 0;
}
Voyons ce qui se passe ici.
je déclare int *i = NULL;
Ca signifie que quelque part dans la mémoire, mettons à l'adresse 100, je reserve une petite place pour ma variable i.
Dans cet emplacement mémoire, je vais mettre la valeur NULL, qui correspond à 0.
Voici donc ce qui se passe:
adresse | contenu
99 | ?
100 | 0
101 | ?
Imagine qu'à ce niveau, tu essaies de faire:
*i = 2
La on va t'envoyer bouler car tu fais *i, ça signifie que tu essaies d'aller à l'adresse 0 pour y mettre la valeur 1. Or 0
est une adresse illégale.
Il faut que tu alloues une zone mémoire et que tu mettes l'adresse dans i. C'est à dire qu'à l'adresse 100, tu dois mettre une adresse qui pointe vers une zone ou tu peux déposer des trucs.
Alors mettons que le profil de alloc ce soit:
void alloc(int *test)
{
test = new int;
}
Tu vas donc faire alloc(i).
Qu'est ce qui se passe quand tu fais ça?
Alloc va avoir sa variable test propre à lui à l'adresse 200 (au pif).
Et la valeur de i sera mise dans la variable test. Or la valeur de i c'est 0 (et non pas son adresse qui est 100).
Voici donc ce qui se passe:
adresse | contenu
200 | 0
Passons donc à
test = new int;
new int va retourner uen adresse vers une zone mémoire ou on peut stocker un entier. On va dire que cette adresse sera 300.
Voici ce qu'on a:
adresse | contenu
200 | 300
Et je te rappelle que pendant ce temps là il y a un endroit qui n'a pas changé:
adresse | contenu
100 | 0
Maintenant la fonction alloc est terminée. Et, comme c'est ce qu'il se passe en général avec une fonction, ses variables seront détruites. Donc test n'existera plus. Ca veut dire que tu as alloué une place dans ta mémoire à l'adresse 300 mais elle est perdue puisqu'il n'y a plus aucun pointeur qui contient cette adresse.
On sort de la fonction alloc donc et on arrive à
*i = 1
Je rappele que i c'est ça:
adresse | contenu
100 | 0
Et qu'avec cette instruction tu essaies de faire ça:
adresse | contenu
0 | 1
Impossible, l'adresse 0 est illégale!
Il faudrait trouver un moyen pour passer l'adresse de i dans alloc plutôt que de passer va valeur (qui est zero).
Et c'est ce que fait un pointeur de référence.
Avec cette fonction:
void alloc(int *&test)
{
test = new int;
}
Voici ce qui se passe quand on fait alloc(i)
alloc va avoir sa variable test, mais l'adresse de cette variable sera la même que celle de i:
adresse | contenu
100 | 0
Donc quand on fera test = new int, il se passera ceci:
adresse | contenu
100 | 300
On sortira de la fonction, et on essaiera de faire *i=1
Et comme l'adresse de i est 100 est que son contenu est l'adresse 300, on aura
adresse | contenu
300 | 1
Et là ya plus de soucis.