En una implementación típica, el tamaño del bloque de memoria dinámica se almacena de alguna manera en el propio bloque; esto es cierto. Pero no hay una forma estándar de acceder a esta información. (Las implementaciones pueden proporcionar formas específicas de implementación para acceder a ella). Así es como está con malloc/free
, así es como está con new[]/delete[]
.
De hecho, en una implementación típica de las asignaciones de memoria prima para new[]/delete[]
llamadas son finalmente procesados por alguna malloc/free
-como par específico de la implementación, lo que significa que delete[]
realmente no tiene que preocuparse por la cantidad de memoria desasignar: simplemente llama al interno free
(o lo que sea que se llame), que se ocupa de eso.
Lo delete[]
no necesita saber es sin embargo el número de elementos a destrucción en situaciones en las que el tipo de elemento de matriz tiene destructor no trivial. Y de eso se trata su pregunta: el número de elementos de la matriz, no el tamaño del bloque (estos dos no son iguales, el bloque podría ser más grande de lo que realmente se requiere para la matriz). Por esta razón, la cantidad de elementos en la matriz normalmente también se almacena dentro del bloque por new[]
y luego se recupera por delete[]
para realizar la destrucción adecuada del elemento de matriz. No hay formas estándar de acceder a este número tampoco.
(Esto significa que en caso general, un bloque de memoria típica asignado por new[]
será independiente, almacenar simultáneamente tanto el tamaño de bloque físico en bytes y el recuento de elemento de matriz. Estos valores se almacenan por diferentes niveles de C++ mecanismo de asignación de memoria - asignador de memoria sin procesar y new[]
respectivamente - y no interactúan entre sí de ninguna manera).
Sin embargo, tenga en cuenta que, por las razones anteriores, el recuento de elementos de matriz normalmente solo se almacena cuando el tipo de elemento de matriz tiene un destructor no trivial. Es decir. este conteo no siempre está presente. Esta es una de las razones por las que no es posible proporcionar una forma estándar de acceder a esos datos: tendrá que almacenarla siempre (lo que desperdicia memoria) o restringir su disponibilidad por tipo de destructor (lo cual es confuso).
Para ilustrar lo anterior, cuando se crea una matriz de int
s
int *array = new int[100];
el tamaño de la matriz (es decir 100
) es no normalmente almacenada por new[]
desde delete[]
no se preocupa de ello (int
no tiene destructor). El tamaño físico del bloque en bytes (como, 400 bytes o más) normalmente se almacena en el bloque mediante el asignador de memoria sin procesar (y utilizado por el desglose de la memoria bruta invocado por delete[]
), pero puede resultar fácilmente 420 para algunos razón específica de la implementación. Por lo tanto, este tamaño es básicamente inútil para usted, ya que no podrá derivar el tamaño de matriz original exacto de la misma.
No es necesario que sepa un buen diseño simple: en un caso complejo, usted mismo debe ocuparse mucho de la administración. En general, hay funciones de depuración para su compilador que le indicarán, pero si lo necesita, probablemente su diseño sea incorrecto. –
A menudo me he preguntado por qué nunca se ve un asignador que no conoce el tamaño, y requiere que se pase borrado. porque ¿con qué frecuencia has venido a eliminar un bloque de memoria y no has podido calcular fácilmente su tamaño? Supongo que nunca debió ser realmente beneficioso implementar un sistema con esta limitación ... – matt
Probablemente impondría restricciones innecesarias a la implementación de una operación de bajo nivel. Después de todo, sí sabías cuánto pediste cuando asignaste el conjunto, por lo que no hay una necesidad apremiante del tiempo de ejecución para decírtelo. – UncleBens