Matriz de acceso más allá del límite en C y C ++

int data[8]; data[9] = 1; 

¿Qué dice el estándar de C ++ al respecto? ¿Es este comportamiento indefinido?

Al menos el comstackdor C (gcc -std = c99 -pedantic -W -Wall) no dice nada al respecto.

Gracias.

El acceso fuera de los límites de la matriz es un comportamiento indefinido, de la sección del proyecto de norma c99 Annex J.2 J.2 El comportamiento indefinido incluye el siguiente punto:

Un subíndice de matriz está fuera de rango, incluso si un objeto es aparentemente accesible con el subíndice dado (como en la expresión lvalue a [1] [7] dada la statement int a [4] [5]) (6.5.6).

y el borrador del estándar C ++ en la sección 5.7 Operadores aditivos, párrafo 5 dice:

Cuando una expresión que tiene un tipo integral se agrega o se resta de un puntero, el resultado tiene el tipo del operando del puntero. Si el operando puntero apunta a un elemento de un objeto de matriz, y la matriz es lo suficientemente grande , el resultado apunta a un desplazamiento de elemento desde el elemento original de modo que la diferencia de los subíndices de los elementos de matriz resultantes y originales es igual a la expresión integral. […] Si tanto el operando del puntero como el resultado apuntan a elementos del mismo objeto de matriz, o uno más allá del último elemento del objeto de matriz, la evaluación no producirá un desbordamiento; de lo contrario, el comportamiento no está definido.

Para completar, la sección 5.2.1 párrafo 1 de suscripción dice:

[…] La expresión E1 [E2] es idéntica (por definición) a * ((E1) + (E2)) [Nota: vea 5.3 y 5.7 para detalles de * y + y 8.3.4 para detalles de matrices. -Finalizar nota]

Es importante tener en cuenta que no es necesario que el comstackdor produzca una advertencia ( diagnóstico ) para un comportamiento indefinido, el borrador del estándar de C ++ en la sección 1.4 párrafo 1 de cumplimiento de la implementación dice:

El conjunto de reglas diagnosticables consta de todas las reglas sintácticas y semánticas en este Estándar Internacional, excepto aquellas que contienen una notación explícita de que “no se requiere diagnóstico” o que se describen como resultado de un “comportamiento indefinido”.

Sí, es un comportamiento indefinido.

Un comstackdor puede o no advertirle contra un comportamiento indefinido, incluso si es capaz de detectarlo.

Esto se considera comportamiento indefinido. Los comstackdores no están obligados a emitir advertencias si intenta comstackr código que dará lugar a un comportamiento indefinido, aunque es bueno que lo hagan.

¡Espero que esto ayude!

Indefinido Puede o no ser memoria inválida, lo que la hace peligrosa. Puede usar herramientas como valgrind para detectar accesos malos como este.

Sí, es un comportamiento indefinido. Todo podría suceder, podría funcionar o no, podría funcionar 2 años y luego detenerse para trabajar. Esto es más peligroso de tres:

  • comportamiento indefinido
  • comportamiento no especificado
  • comportamiento definido por la implementación

Puede verificar esto para conocer a otros parientes: ¿Cuál es el comportamiento indefinido común que un progtwigdor de C ++ debe conocer?

Comportamiento indefinido, no especificado y definido por la implementación

C y C ++ no verifican los límites. Los valores que intenta alcanzar podrían ser prácticamente cualquier cosa. Puede parecer que funciona en su comstackdor, pero no es legal C o C ++, y no hay garantía de que funcione la próxima vez que ejecute el progtwig.

De acuerdo con el estándar ISO C, acceder a una matriz fuera de las causas de los rebotes

Comportamiento indefinido: comportamiento, al usar una construcción de progtwig errónea o no portable o datos erróneos, para los cuales esta Norma Internacional no impone requisitos.

Las fallas de segmentación ocurren cuando intenta desreferenciar un puntero a la memoria a la que su progtwig no tiene acceso, y el hecho de pasar el final de su matriz probablemente no cause eso. Pero es muy probable que le dé algunos malos valores.

Sí, es un comportamiento indefinido, algunos comstackdores dan advertencias al respecto, otros no, pero veamos, lo hace su código.

Mire la implementación en línea de los operadores [] . a[b] realidad es *(a + b) . Así que vuelve a tu código.

 int data[8]; data[9] = 1; 

Primero asigna una parte de la stack y crea un puntero al primer elemento. Luego reescribes algunos datos, que están justo después de tu matriz, por lo que corrompes algunos datos.

Tomemos otro ejemplo:

 int data[8]; int data2[8] = {}; data[9] = 1; 

Es muy probable que el comstackdor genere código que asigna una vez y crea dos punteros como matrices. Entonces los data[9] = 1; puede establecer el segundo valor de data2 a uno, sin embargo, no hay garantías al respecto.