¿La matriz es más grande que la asignada?

Tengo una matriz que está declarada como bu buff [8]. Eso debería ser solo de 8 bytes, pero teniendo en cuenta el ensamblaje y la prueba del código, obtengo una falla de segmentación cuando ingreso algo más de 32 caracteres en ese buff, mientras que esperaría que fuera más de 8 caracteres. ¿Por qué es esto?

Lo que estás diciendo no es una contradicción:

  • Tienes espacio para 8 personajes.

  • Recibes un error cuando ingresas más de 32 caracteres.

¿Y qué?

El punto es que nadie le dijo que se le garantizaría un error si ingresa más de 8 caracteres. Eso es simplemente un comportamiento indefinido , y cualquier cosa puede suceder (y sucederá).

Absolutamente no debe pensar que la ausencia de mal comportamiento obvio es una prueba de la exactitud de su código. La corrección del código solo se puede verificar comparando el código con las reglas del idioma (aunque algunas herramientas automatizadas como valgrind son una gran ayuda).

Escribir más allá del final de la matriz es un comportamiento indefinido. El comportamiento indefinido significa que no se garantiza nada (incluido un error de segmentación).

En otras palabras, podría hacer cualquier cosa. Más práctico, es probable que la escritura no toque nada protegido, por lo que desde el punto de vista del sistema operativo todo está bien hasta 32.

Esto plantea un punto interesante. Lo que es “totalmente incorrecto” desde el punto de vista de C podría estar bien con el sistema operativo. Al sistema operativo solo le importa a qué páginas accede:

  • ¿Se asigna la dirección para su proceso?
  • ¿Tu proceso tiene los derechos?

No debe contar con que el sistema operativo le dé una bofetada si algo sale mal. Una herramienta útil para esto (bofetadas) es valgrind, si está usando Unix. Le advertirá si su proceso está haciendo cosas desagradables, incluso si esas cosas desagradables están técnicamente bien con el sistema operativo.

Las matrices C no tienen comprobación de límite.

Como han dicho otros, estás golpeando un comportamiento indefinido; Hasta que te quedes dentro de los límites de la matriz, todo funciona bien. Si haces trampa, en lo que se refiere al estándar, cualquier cosa puede suceder, incluido tu progtwig que parece funcionar bien, así como la explosión del sol.

Lo que sucede en la práctica es que, con las variables asignadas a la stack, es probable que se sobrescriban otras variables en la stack, se obtengan errores “imposibles” o, si alcanza un valor canario asignado por el comstackdor, puede detectar el desbordamiento del búfer al regresar. la función. Para las variables asignadas en el denominado montón, el asignador del montón puede haber dado un poco más de espacio que el solicitado, por lo que el error puede ser menos fácil de detectar, aunque puede desordenar fácilmente las estructuras internas del montón.

En ambos casos, también puede acceder a una página de memoria protegida, lo que hará que su progtwig se cierre por la fuerza (para la stack esto ocurre con menos frecuencia porque generalmente tiene que sobrescribir la stack completa para llegar a una página protegida).

Su statement char buff[8] suena como una variable asignada a la stack, aunque podría ser asignada al montón si es parte de una estructura. El acceso fuera de los límites de una matriz es un comportamiento indefinido y se conoce como una saturación del búfer. El exceso de búfer en la memoria asignada de la stack puede dañar el marco de stack actual y posiblemente otros marcos de stack en la stack de llamadas. Con un comportamiento indefinido, cualquier cosa podría suceder, incluso sin error aparente. No esperaría una falla de Seg inmediatamente porque la stack es típicamente cuando el hilo comienza.

Para la memoria asignada al montón, los administradores de memoria suelen asignar grandes bloques de memoria y luego asignarlos de esos bloques más grandes. Es por eso que a menudo no se produce un error de seguridad cuando se accede más allá del final de un bloque de memoria.

Es un comportamiento indefinido para acceder más allá del final de un bloque de memoria. Y es perfectamente válido, de acuerdo con el estándar, para que tales accesos fuera de límites resulten en fallas seg o en una lectura o escritura aparentemente exitosa. Digo que aparentemente tiene éxito porque si está escribiendo, es muy probable que produzca una corrupción del montón escribiendo fuera de límites.

A menos que no nos diga algo, respondió a su pregunta de owflown.

declarando

 char buff[8] ; 

Significa que el comstackdor agarra 8 bytes de memoria. Si intentas y metes 32 caracteres en él, deberías tener una falla de seg, que se llama desbordamiento de búfer.

Cada caracter es un byte (a menos que esté haciendo unicode en el que es una palabra), por lo que está tratando de poner 4 veces el número de caracteres que caben en su búfer.

¿Es esta la primera vez que codificas en C?