2010-04-13 14 views
6

Esta puede ser una pregunta muy simple, pero por favor, ayúdenme.borrar y nuevo en C++

quería saber exactamente lo que sucede cuando llamo nueva & eliminar, por ejemplo en el código de abajo

char * ptr=new char [10]; 

delete [] ptr; 

llamada a la nueva yo retornos de direcciones de memoria. Asigna 10 bytes exactos en el montón, donde se almacena información sobre el tamaño. Cuando llamo a eliminar en el mismo puntero, veo en el depurador que hay un montón de bytes cambiados antes y después de los 10 bytes.

¿Hay algún encabezado para cada nuevo que contiene información sobre el número de bytes asignado por nuevo.

Muchas gracias

+2

Puede ser de ayuda: http://stackoverflow.com/questions/2327848/how-does-the-delete-in-c-know-how-many-memory-locations-to-delete – codaddict

Respuesta

13

No se asignan exactamente 10 bytes

Eso es dependiente de la implementación. La garantía es "al menos 10 caracteres".

¿Dónde se almacena información sobre el tamaño?

Depende de la implementación.

¿Hay algún encabezado para cada elemento nuevo que contenga información sobre el número de bytes asignados por uno nuevo?

Depende de la implementación.

Por "eso depende de la implementación" quiero decir que no está definido en el estándar.

0
char * ptr=new char [10]; 

Usted está creando una matriz de 10 caracteres en el montón de almacenamiento y la dirección del elemento de 0º en un pointer.this es similar a hacer un malloc en C

delete [] ptr; 

Está eliminando (liberando la memoria) la memoria del montón que fue asignada por la declaración anterior. Esto es similar a hacer una libre en c.

3

Es completamente dependiente de la implementación. En general, debe almacenar la cantidad de elementos en otro lugar. La implementación debe asignar suficiente espacio para al menos la cantidad de elementos especificados, pero puede asignar más.

3

¿Hay algún encabezado para cada nuevo que contiene información sobre el número de bytes asignado por nuevo.

Eso depende de la plataforma, pero sí, en muchas plataformas existen.

5

Todo depende del compilador y la biblioteca de tiempo de ejecución. Solo se define exactamente qué efectos tienen new y delete en su programa, pero no se especifica cómo se logran exactamente.

En su caso, parece que se asigna un poco más de memoria que la solicitada y probablemente almacenará información de administración como el tamaño del fragmento actual de memoria, información sobre áreas adyacentes de espacio libre o información para ayudar al depurador a intentar detectar desbordamientos de búfer y problemas similares.

2

Precisamente, de acuerdo con la norma, new char[10] asignará al menos 10 bytes en el montón.

Las partes internas de new y delete dependen de la implementación. Por lo tanto, variará de compilador a compilador y de plataforma a plataforma. Además, puede encontrar una variedad de algoritmos de asignación (por ejemplo, TCMalloc).

Le daré una visión general de cómo podría trabajar internamente, pero no lo tome como la verdad absoluta. Está escrito con el único propósito de esta explicación.

En resumen, el operador new invoca internamente malloc. El malloc usa una lista muy larga de bloques de memoria disponibles, también conocido como free chain. Cuando se invoca malloc, busca esta lista para el primer bloque que sea lo suficientemente grande como para contener el tamaño solicitado. Después de eso, divide el bloque en dos partes, una con el tamaño que solicitaste y la otra con el resto, que luego se agrega a la cadena libre. Finalmente, devuelve el bloque con el tamaño de la solicitud.

Lo inverso ocurre en una llamada free, que se invoca mediante eliminar/borrar []. En resumen, devuelve el bloque proporcionado al free chain.

Podría haber trucos extravagantes durante los procesos que describí arriba, como ordenar el free chain, redondear el tamaño solicitado a la siguiente potencia de dos para reducir la fragmentación de la memoria, y así sucesivamente.

+0

'new' doesn 't necesita confiar en 'malloc'.Eso también depende de la implementación :) –

+0

@Axel correcto, si no hice clara la segunda oración, házmelo saber, para que pueda aclarar. O incluso agregue un comentario adicional antes de la descripción general. Básicamente fue para dar una idea de cómo funciona. – jweyrich

0

Depende de la implementación, pero la mayoría de los metadatos para un bloque de memoria generalmente se almacenan en el área antes de que se devuelva la dirección de memoria. El cambio que observó antes de los 10 bytes probablemente fue la actualización de los metadatos para este bloque (probablemente el tamaño del bloque se escribió en los metadatos) y después de los 10 bytes se actualizaron los metadatos para el siguiente bloque (aún no asignado, probablemente el puntero al siguiente fragmento en la lista libre).

No es una buena idea meterse con el montón porque no es portátil. Sin embargo, si desea hacer semejante montón de magia, le sugiero que implemente sus propios grupos de memoria (solo obtenga una gran cantidad de memoria del montón y adminístrelo usted mismo). Un posible lugar para comenzar sería mirar libmm.

0

Si bien los detalles dependen de la implementación, una pieza de información que la implementación necesitará almacenar es la cantidad de elementos en la matriz. O si no lo almacena directamente, deberá derivarlo con precisión del tamaño de bloque asignado.

El motivo es que si una matriz de objetos se asigna con new [], cuando se eliminan con delete [], se deberá invocar al destructor de cada objeto de la matriz. delete [] necesitará saber cuántos objetos destruir. Es por eso que es necesario hacer coincidir nuevo con delete y new [] con delete [].