La risposta breve è che l'indice 10 è oltre i limiti della matrice vec
e scrivere un doppio di 8 byte su vec[10]
potrebbe sovrascrivere il puntatore di base della funzione precedente e l'indirizzo di risposta della funzione - a seconda di come il compilatore alloca la memoria sullo stack per le variabili locali.
Ecco un diagramma dello stack di runtime quando è stato chiamato func
(si presume l'architettura x86):
<------------ 4 bytes ----------->
.
.
.
+---------------------------------+
| data2 |
+---------------------------------+ arg 3 (8 bytes)
| data2 |
+---------------------------------+
| data1 |
+---------------------------------+ arg 2 (8 bytes)
| data1 |
+---------------------------------+
| i | arg 1
+---------------------------------+
| return address | < 8 bytes to <--\
+---------------------------------+ < be overwritten |
| previous ebp (old base pointer) | <-- "vec[10]" < by data1 |
+---------------------------------+ | stack
| vec[9] | | frame
+---------------------------------+ | for
| vec[8] | | "func"
+---------------------------------+ |
. |
. |
. |
+---------------------------------+ |
| vec[1] | |
+---------------------------------+ |
| vec[0] | <--/
+---------------------------------+
Si noti che la disposizione della memoria allocata per le variabili locali in uno stack frame è determinata dal compilatore. Ciò significa che l'allineamento dello stack può comportare "spazio allentato" che, ad esempio, elimina il calcolo dell'offset del buffer. Inoltre, se il compilatore alloca la memoria per la variabile p
tra il ebp
salvato e la memoria allocata per l'array vec
, p
verrà sovrascritto anziché il vecchio ebp
e l'indirizzo di ritorno di func
.
Per maggiori informazioni sul layout dello stack frame vedi: