Pregunta

vi algo de código como a continuación durante una sesión de pares de código de revisión:

char *s = new char[3];
*s++ = 'a';
*s++ = 'b';
*s++='\0';
delete []s; // this may or may not crash on some or any day !!

En primer lugar, sé que en el estándar de C ++, que apunta a un más allá de la matriz de tamaño es ¡muy bien aunque el acceso se traduce en un comportamiento indefinido. Así que creo que la última línea de *s++='\0' está muy bien. Pero si no recuerdo mal, los mandatos de C ++ estándar que delete deben ser suministrados al mismo puntero que new regresó.

Esto creo que significa que el puntero devuelto no debe ser manipulado, con. Supongo que se debe a new podría mantener cierta información de limpieza antes de la dirección devuelta delete que podría utilizar. Al mover el puntero new'd podría hacer esta inaccesible.

Es un comportamiento indefinido o definido por la implementación o no especificado? Puede alguien confirmar esto por favor? Preferiblemente señalando el lugar correcto en el estándar de C ++.

En el proyecto de versión libre disposición del proyecto de C Standard ++ (Draft_SC22-N-4411.pdf) tiene los detalles en la sección 5.3.5. Lo conseguí en la página principal de Bjarne.

¿Fue útil?

Solución

Desde el estándar de C ++, sección 5.3.5 / 2:

  

el valor del operando de borrado será el valor del puntero   que resultó de una matriz anterior   nueva expresión. Si no es así, el comportamiento   está definido

Otros consejos

Sí, debe eliminar [] el puntero original que estuvieron a cargo de nuevo; en este caso, eso sería un puntero a la cabeza de la matriz, en lugar de la cola. El código aquí está eliminando algún otro objeto al azar no especificada.

Sí, recuerdan cómo se implementa a menudo: nueva realidad llama a malloc, que devuelve un puntero a (void*)(&(((int*)p)[1])), donde p es el comienzo real de la memoria asignada, y el primer int es el tamaño de la memoria real regresamos .

El puntero volvamos es una sizeof (int) (o lo que sea la alineación requiere) más adelante en la memoria real asignada. Nos acostamos nuestro objeto allí, dejando el tamaño real sin ser molestados.

A continuación, cuando ese puntero pasado a eliminar, que pasa a libre, libre parece una int antes el puntero pasado, para encontrar el tamaño que está siendo devuelto.

Al pasar de vuelta algo distinto de lo que nos va a significar que el libre piensa en una cantidad arbitraria de memoria real se pasa de nuevo, y va a arruinar la lista libre en consecuencia.

Una vez más, esta es la forma en que es a menudo en práctica, no la forma nueva, borrar, malloc, o libre están obligados a ponerse en práctica.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top