Una aplicación de prueba simple:
cout << new int[0] << endl;
salidas:
0x876c0b8
Entonces parece que funciona. ¿Qué dice la norma sobre esto? ¿Es siempre legal "asignar" un bloque de memoria vacío?
Una aplicación de prueba simple:
cout << new int[0] << endl;
salidas:
0x876c0b8
Entonces parece que funciona. ¿Qué dice la norma sobre esto? ¿Es siempre legal "asignar" un bloque de memoria vacío?
Respuestas:
Desde 5.3.4 / 7
Desde 3.7.3.1/2
también
Eso significa que puede hacerlo, pero no puede desreferenciar legalmente (de una manera bien definida en todas las plataformas) la memoria que obtiene, solo puede pasarla a la eliminación de matriz, y debe eliminarla.
Aquí hay una nota interesante (es decir, no es una parte normativa de la norma, pero se incluye con fines expositivos) adjunta a la oración de 3.7.3.1/2
fuente
new[]
con undelete[]
- cualquiera sea el tamaño. En particular, cuando llamanew[i]
, necesita un poco más de memoria que la que está tratando de asignar para almacenar el tamaño de la matriz (que luego se utilizadelete[]
cuando se desasigna)Sí, es legal asignar una matriz de tamaño cero como esta. Pero también debes eliminarlo.
fuente
int ar[0];
es ilegal, ¿por qué está bien nuevo?sizeof (type)
se espera que nunca devuelva cero. Ver por ejemplo: stackoverflow.com/questions/2632021/can-sizeof-return-0-zeroCada objeto tiene una identidad única, es decir, una dirección única, lo que implica una longitud distinta de cero (la cantidad real de memoria aumentará silenciosamente, si solicita cero bytes).
Si asignó más de uno de estos objetos, encontrará que tienen direcciones diferentes.
fuente
operator []
también almacena el tamaño de la matriz en algún lugar (ver isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-array ). Entonces, si la implementación asigna el recuento de bytes con los datos, simplemente podría asignar el recuento de bytes y 0 bytes para los datos, devolviendo el último puntero.operator new[]
deberían devolver diferentes punteros. Por cierto, elnew expression
tiene algunas reglas adicionales (5.3.4). No pude encontrar ninguna pista de quenew
con el tamaño 0 se requiera para asignar algo. Lo siento, rechacé porque encuentro que su respuesta no responde las preguntas, sino que proporciona algunas declaraciones controvertidas.new[]
implementación devuelva direcciones en un rango donde no hay memoria dinámica asignada, por lo tanto, realmente no usa ninguna memoria (mientras usa el espacio de direcciones)while(!exitRequested) { char *p = new char[0]; delete [] p; }
bucle sin reciclar punteros colapsaría en polvo antes de que posiblemente se quedara sin espacio de direcciones, pero en una plataforma con punteros de 32 bits sería Suposición mucho menos razonable.Sí, es completamente legal asignar un
0
bloque de tamañonew
. Simplemente no puede hacer nada útil con él ya que no hay datos válidos para acceder.int[0] = 5;
es ilegal.Sin embargo, creo que el estándar permite cosas como
malloc(0)
regresarNULL
.También necesitará
delete []
cualquier puntero que obtenga de la asignación también.fuente
Encontré que Efective C ++ Third Edition decía así en "Elemento 51: Adherirse a la convención al escribir nuevo y eliminar".
fuente
Le garantizo que el nuevo int [0] le cuesta espacio extra desde que lo probé.
Por ejemplo, el uso de memoria de
es significativamente más pequeño que
El uso de memoria del segundo fragmento de código menos el del primer fragmento de código es la memoria utilizada para los numerosos nuevos int [0].
fuente