2010-01-09 21 views
14

¿Es cierto que un puntero asignado a la dirección de inicio de una matriz dinámicamente asignada no tiene la información del tamaño de la matriz? Entonces tenemos que usar otra variable para almacenar su tamaño para luego procesar la matriz a través del puntero.tamaño de la matriz dinámicamente asignada

Pero cuando liberamos la matriz dinámicamente asignada, no especificamos el tamaño, sino que simplemente "ptr libre" o "eliminar [] ptr". ¿Cómo podría liberar o eliminar el tamaño de la matriz? ¿Podemos usar el mismo esquema para evitar almacenar el tamaño de la matriz en otra variable?

Gracias!

Respuesta

18

Sí, esto es cierto.

delete conoce el tamaño del fragmento de memoria porque new agrega información adicional al fragmento (generalmente antes de que el área sea devuelta al usuario), que contiene su tamaño, junto con otra información. Tenga en cuenta que esto es muy específico de la implementación y su código no debe usarlo.

Así que para responder a su última pregunta: No - no podemos usarlo - es un detalle de implementación que depende de la plataforma y del compilador.


Por ejemplo, en el asignador de memoria de muestras demostrado en K & R2, este es el "header" colocado antes de cada trozo asignado:

typedef long Align; /* for alignment to long boundary */ 

union header { /* block header */ 
    struct { 
    union header *ptr; /* next block if on free list */ 
    unsigned size; /* size of this block */ 
    } s; 

    Align x; /* force alignment of blocks */ 
}; 

typedef union header Header; 

size es el tamaño del bloque asignado (que es luego usado por free, o delete).

+1

Tenga en cuenta que el tamaño del bloque asignado desde el punto de La vista de la implementación del asignador puede ser mayor que el tamaño solicitado por el usuario. –

+0

Además, más allá del tamaño del bloque subyacente sin procesar, si un tipo T tiene un destructor, entonces el sistema debe almacenar 'n' pasado a' new T [n] '_somewhere_ para que pueda llamar al destructor' n' veces cuando 'delete []' es llamado. Por supuesto, cómo y dónde almacena 'n' sigue siendo tan específico como el almacenamiento del tamaño del bloque sin procesar. –

3

Es cierto que la matriz no contiene el tamaño de la matriz, debe almacenar esa información para más adelante. Cuando borre una matriz a través de delete o free, será el puntero a la memoria asignada que pase. El administrador de memoria utilizado (ya sea por el sistema o por su propia costumbre al anular el nuevo y eliminar) conoce el área de memoria que se libera y realiza un seguimiento de la misma. Espero que tenga sentido.

2

Sí, es cierto. Esto es parte de por qué rara vez debe tratar de lidiar con esto directamente, y usar un contenedor estándar en su lugar. El único momento en que tiene sentido tratar con esto es si usted mismo decide implementar un contenedor (en ese caso, normalmente hará un seguimiento de la información de tamaño en la implementación de su contenedor).

7

Lo curioso es que históricamente era delete [20] arr; como lo es arr = new int[20]. Sin embargo, la práctica demostró que el asignador puede almacenar sin problemas la información sobre el tamaño, y dado que la mayoría de las personas que la usaban la almacenaban de todos modos, se agregó al estándar.

Lo que es más divertido, y poco conocido, es el hecho de que esta "sintaxis de eliminación extendida" es respaldada por algunos compiladores de C++ (a pesar de ser incorrecto incluso ante el estándar C++ 98), aunque ninguno lo requiere

int* arr = new int[20]; 
delete [20] arr; 

La parte triste de todo esto es sin embargo, que no hay manera de que sigan los estándares para recuperar ese tamaño aprobado para su uso: -/

+0

Podría ser "compatible", no es parte del estándar C++. –

+0

Cierto, amplié mi respuesta un poco. Me pregunto si hay algún documento estándar disponible que produzca documentos que "caractericen". –

Cuestiones relacionadas