Considerar
int main()
{
auto a = new int[0];
delete[] a; // So there's no memory leak
}
Entre la inicialización y la eliminación de la copia, ¿puede leer el puntero en a + 1?
Por otra parte, el lenguaje no permite que el compilador conjunto ade nullptr?
c++
language-lawyer
Betsabé
fuente
fuente

acon seguridad (ciertamente no puedes desreferenciarlo).a + 1", ¿el código siguiente esauto b = a + 1;comportamiento indefinido? (Creo que es).0sea el resultado de alguna expresión que no sabrás hasta el tiempo de ejecución. Comonew int[0]es seguro, podría ahorrarse la preocupación de algunas ramificaciones / casos especiales. Imagínese si tuviera que inicializar unstd::vectorconstd::vector<int> v(0);.Respuestas:
De acuerdo con [basic.compound.3] , el valor almacenado
adebe ser uno de los siguientes:int)Podemos descartar la primera posibilidad ya que no se
intconstruyeron objetos de tipo . Se descarta la tercera posibilidad ya que C ++ requiere que se devuelva un puntero no nulo (consulte [basic.stc.dynamic.allocation.2] ). Por lo tanto, nos quedan dos posibilidades: un puntero más allá del final de un objeto o un puntero no válido.Me inclinaría a ver
acomo un puntero pasado-fin, pero no tengo una referencia acreditada para establecer definitivamente eso. (Sin embargo, hay una fuerte implicación de esto en [basic.stc] , ver cómo puedes usardeleteeste puntero). Así que consideraré ambas posibilidades en esta respuesta.El comportamiento es indefinido, según lo dictado por [expr.add.4] , independientemente de la posibilidad que se aplique desde arriba.
Si se
atrata de un puntero pasado, se considera que apunta al elemento hipotético en el índice0de una matriz sin elementos. Agregar el enterojaase define solo cuando0≤0+j≤n, dondenes el tamaño de la matriz. En nuestro caso,nes cero, por lo que la sumaa+jse define solo cuandojes0. En particular, la suma1no está definida.Si
ano es válido, entonces caemos claramente en "De lo contrario, el comportamiento no está definido". (No es sorprendente que los casos definidos solo cubran valores de puntero válidos).No. De la mencionada [basic.stc.dynamic.allocation.2] : "Si la solicitud tiene éxito, el valor devuelto por una función de asignación reemplazable es un valor de puntero no nulo" . También hay una nota al pie que dice que C ++ (pero no C) requiere un puntero no nulo en respuesta a una solicitud cero.
fuente
Según una discusión reciente del reflector del CWG como resultado del número editorial 3178 , se
new int[0]produce lo que actualmente se denomina un valor de puntero "pasado al final" .Se deduce que
ano puede ser nulo ya + 1no está definido por [expr.add] / 4 .fuente
new int[0]produce lo que actualmente se denomina" valor de puntero "pasado". Esto no es exacto. No hubo mucha discusión. Una persona sugirió que el valor debería ser "puntero más allá del final de un objeto", y esta afirmación fue cuestionada porque en el caso de una matriz con0elementos, no hay ningún objeto para superar el final.a + 1no está definido en ningún caso, por lo que su punto solo se refiere a siapuede ser nulo.a + 1no está definido y tal vez el valor del puntero resultante se denominará "puntero pasado el final". No digo que la respuesta sea incorrecta. No es exacto porque podría entenderse que hubo una larga discusión con un consenso de que la simple especificación de que el resultado es "puntero más allá del final" es suficiente para resolver el problema. El problema con "puntero más allá del final" es que es más allá del final de algún objeto y restar1de dicho valor de puntero le da a uno un puntero al objeto, lo que probablemente no debería ser el caso para las matrices de0elementos.