primero - leer antes de escribir no está definido con memoria mallada?
se aprende primero a leer o a escribir (3)
Racionalmente tiene que ser indefinido. De lo contrario, el comportamiento necesario de un programa C que se ejecute en algo como Valgrind, que diagnostica lecturas de memoria no inicializada y arroja errores apropiados cuando ocurren, sería ilegal según el estándar.
Leyendo el estándar, la pregunta clave es si los valores de memoria malloc''ed son "valores no especificados" (que debe ser algún valor legible), o "valores indeterminados" (que pueden contener representaciones trampa, cf definición 3.17.2.)
Según 7.20.3.3, citado en las otras respuestas, malloc devuelve un bloque de memoria que contiene valores indeterminados y, por lo tanto, puede contener representaciones de trampas. La discusión relevante de las representaciones de trampas es 6.2.6.1, parte 5:
Ciertas representaciones de objetos no necesitan representar un valor del tipo de objeto. Si el valor almacenado de un objeto tiene tal representación y es leído por una expresión lvalue que no tiene un tipo de carácter, el comportamiento no está definido. ... Tal representación se llama una representación de trampa .
Ahí vas. Básicamente, se permite que la implementación C detecte (es decir, "intercepte") referencias a valores indeterminados, y trate ese error como lo desee, incluso de formas no definidas.
De acuerdo con este hilo de comentarios reddit , no está definido si se intenta leer la memoria antes de que se haya escrito. Me refiero a la memoria de pila normal que se ha malloc
éxito.
... tenga en cuenta que esto no es estrictamente válido C: el sistema de compilación / tiempo de ejecución puede inicializar la memoria no inicializada con las llamadas representaciones de trampas, que causan un comportamiento indefinido en el acceso.
Encuentro esto difícil de creer. ¿Hay una cita estándar?
Por supuesto, entiendo que no hay garantía de que la memoria se haya reducido a cero. Los valores en esta memoria no inicializada son esencialmente pseudoaleatorios o arbitrarios. Pero realmente no puedo creer que el Estándar se refiera a esto como un comportamiento indefinido (en el sentido de que podría segfault, o eliminar todos sus archivos, o lo que sea). El resto del hilo de reddit no arrojó más luz sobre este tema.
Si se accede a través de un char*
, esto está definido. Pero de lo contrario, este es un comportamiento indefinido.
(C99, 7.20.3.3) "La función malloc asigna espacio para un objeto cuyo tamaño se especifica por tamaño y cuyo valor es indeterminado".
en valor indeterminado:
(C99, 3.17.2p1) "valor indeterminado: un valor no especificado o una representación de trampa"
en la representación de trampas, la lectura a través de un tipo no característico es un comportamiento indefinido:
(C99, 6.2.6.1p5) "Ciertas representaciones de objetos no necesitan representar un valor del tipo de objeto. Si el valor almacenado de un objeto tiene tal representación y es leído por una expresión lvalue que no tiene un tipo de carácter, el comportamiento es indefinido. [...] Tal representación se llama representación de trampas ".
ISO / CEI 9899: 1999 , 7.20.3.3 La función malloc:
La función malloc asigna espacio para un objeto cuyo tamaño se especifica por tamaño y cuyo valor es indeterminado.
6.2.6.1 Representación de tipos, §5:
Ciertas representaciones de objetos no necesitan representar un valor del tipo de objeto. Si el valor almacenado de un objeto tiene tal representación y es leído por una expresión lvalue que no tiene un tipo de carácter, el comportamiento no está definido.
Y la nota al pie 41 lo hace aún más explícito (al menos para las variables automáticas):
Por lo tanto, una variable automática se puede inicializar en una representación de captura sin causar un comportamiento indefinido, pero el valor de la variable no se puede usar hasta que se almacene un valor apropiado en ella.