¿Qué es un "pisotón de memoria"?

95

Acabo de encontrarme con esta publicación de blog que menciona "pisando fuerte la memoria":

un programa en C ++ que es fácilmente capaz de pisotear la memoria (algo de lo que probablemente nunca haya oído hablar si nació en un mundo de código administrado).

¡Y de hecho nunca he oído hablar de él!

Entonces, ¿qué es esto, un recuerdo pisando fuerte, un recuerdo pisando fuerte? ¿Cuándo ocurre?

scravy
fuente
4
Un buen ejemplo de un pisotón de memoria es esta pregunta: stackoverflow.com/questions/31016660/…
Phillip Ngan

Respuestas:

117

La memoria se "pisotea" cuando un fragmento de código manipula la memoria sin darse cuenta de que otro fragmento de código está utilizando esa memoria de una manera que entra en conflicto. Hay varias formas comunes en que se puede pisotear la memoria.

Uno es asignar, digamos, 100 bytes de memoria pero luego almacenar algo más allá de la dirección 100. Esta memoria podría usarse para guardar algo completamente diferente. Esto es particularmente difícil de depurar porque el problema aparecerá cuando algo intente acceder a la víctima que fue pisoteada y el código que pisoteó puede no tener ninguna relación.

Otro es acceder a la memoria después de que se liberó. La memoria puede asignarse a otro objeto. Nuevamente, el código que muestra el problema puede estar relacionado con el objeto recién asignado que obtuvo la misma dirección y no relacionado con el código que causó el problema.

David Schwartz
fuente
3
Aquí hay un buen ejemplo de memoria pisada.
patryk.beza
33

Muy a menudo se trata de un desbordamiento del búfer; como ejemplo, este código:

char buffer[8];
buffer[8] = 'a';

"pisoteará" lo que sea que esté en la siguiente cosa en la memoria buffer. En términos generales, "pisando fuerte" es cuando la memoria se escribe involuntariamente.

IronMensan
fuente
9

Otras respuestas son básicamente correctas, pero me gustaría dar un ejemplo.

int a[10], i;       
for (i = 0; i < 11 ; i++)
    a[i] = 0;

int i, a[10];     
for (i = 0; i < 11 ; i++)
    a[i] = 0;

Estas muestras pueden dar lugar a un bucle infinito (o no), porque es un comportamiento indefinido.

Es muy probable que la variable ien la memoria se almacene justo después de la matriz. Por lo tanto, acceder a[10]podría acceder ien otras palabras, podría restablecer el contador de bucle.

Creo que es un buen ejemplo que demuestra la memoria "pisando fuerte".

ST3
fuente
1
Hay otro hilo, discutiendo prácticamente el mismo ejemplo en un sistema operativo diferente ... stackoverflow.com/questions/31016660
Christian
2
@Christian No tiene nada que ver con un SO. Este es un comportamiento indefinido.
ST3