Succede perché quando chiami la funzione sul ramo destro questa riceve lo stesso valore di i della funzione che ha operato sul sinistro. E' un po' difficile da spiegare, ma avviene una cosa del genere:
- 1^ chiamata della funzione: i vale 0 e viene incrementato a 1;
- 2^ chiamata (all'interno della prima): è la funzione che opera sul sinistro. i vale 1 e viene incrementato a 2;
Supponiamo persemplicità che il ramo sinistro sia già finito:
- si torna alla funzione 1, che però non può sapere di quanto è stato incrementato i nel ramo sinistro. Quindi i vale ancora 1;
- 3^ chiamata (sempre all'interno della prima): è la funzione che opera sull'altro ramo. i vale 1 e viene incrementato a 2;
eccetera.
potresti risolvere facendo ritornare i, in questo modo:
int caricaarray(struct tree *albero,int *a,int i,int n){
if(albero!=NULL){
if(i<n){
a[i]=albero->x;
i=i+1;
}
i=caricaarray(albero->left,a,i,n);
i=caricaarray(albero->right,a,i,n);
}
return i;
}