6

Si tengo la siguiente declaración: la memoriaC++ - La asignación de memoria en el montón usando "nueva"

int *x = new int;

En este caso, he asignado dinámicamente en el montón. En otras palabras, ahora tengo una dirección de memoria reserved para un objeto int.

decir después de eso que me hizo el siguiente:

delete x;

Lo que significa que freed up la dirección de memoria en el montón.

decir después de eso me di el siguiente nuevo:

int *x = new int;

Will x punto a la dirección de memoria de edad misma se señaló en el montón antes de que se haya eliminado?

¿Qué pasa si hice esto antes delete:

x = NULL;

Y, a continuación, hizo esto:

int *x = new int;

Will x punto a AA dirección de memoria en el montón otra de ¿el viejo?

Gracias.

+1

Con solo establecer un puntero a 'NULL', usted está no borrarlo Si luego hace 'new int', la memoria anterior seguirá en uso (sin un puntero, es una pérdida de memoria) y, por supuesto,' new' * siempre * apunta a una * nueva * dirección - de ahí el nombre. –

Respuesta

1

No, no hay tal garantía. Esto depende completamente del asignador utilizado para satisfacer su solicitud de memoria. Sin embargo, C++ es la bestia poderosa que es, deja que anules el nuevo operador. Puede crear un asignador personalizado (gestión de memoria) que proporcione memoria de cierta manera, lo que a veces es muy útil.

+0

¿Podría dar un ejemplo? ¿Cómo se asignaría memoria sin usar 'new' y para qué se usa un asignador personalizado? –

+0

Los asignadores personalizados se pueden usar para proporcionar una cantidad fija de memoria secuencial. En lo que respecta al rendimiento y, por lo general, en los juegos, es preferible contar con buenos patrones de acceso a memoria secuencial. Un recolector de basura (gestión automática de la memoria) generalmente proporciona esto asignando este cierre en el tiempo. Un asignador lineal simple podría hacer lo mismo y también puede moverse alrededor de las cosas en un montón pequeño ya que las cosas se eliminan para evitar agujeros y tomar en consideración otras restricciones de hardware para mejorar el rendimiento de la memoria en el futuro. –

+0

Para ver más ejemplos, puede ver esta página http://www.cprogramming.com/tutorial/operator_new.html Estoy bastante seguro de que es posible anular el asignador predeterminado, por lo cual, anularía la operación 'new int'. –

1

No, el puntero devuelto desde el segundo new int; puede apuntar a cualquier lugar dentro de la dirección de escritura válida. No hay garantía de que se use la región desasignada previamente (de hecho, la mayoría de las veces puede que no, ya que el administrador del montón puede elegir liberar la memoria real en algún momento posterior).

1

Al hacer esto antes de borrar:

x = NULL; 

entonces es una memoria de fugas . Pierdes memoria que no sirve para nada, y que no puedes liberar porque perdiste la dirección. (puede eliminar un puntero nulo, simplemente no hace nada)

Hacer esto demasiado tiempo puede provocar un bloqueo/ralentización del sistema más aceptable porque se desperdicia toda su memoria. (utilizando swap en disco demasiado etc ... etc ...)

No espere obtener la misma nueva dirección exacta después de una eliminación, y luego una nueva. Aunque puede suceder de vez en cuando, al azar.

1

1) Después de la liberación, si asigna nuevamente usando la misma variable, no hay garantía de que vaya a obtener la misma porción de memoria. Piense en cómo se implementa lo nuevo, se puede hacer de cualquier manera que pueda imaginar, incluso utilizando asignadores personalizados. Además, es posible que otro subproceso usó nuevo entre llamadas gratuitas() y nuevas() y 'robó' su memoria

2) No lo haga. Está perdiendo referencia y si aplica el operador de eliminación en el puntero NULL, no hará nada. Por lo tanto, es posible que tenga una pérdida de recursos si no almacena la referencia en otra variable. Si llama nuevo otra vez será definitivamente asignar a otra parte si se asume que nadie cancela la asignación del área otorgada por primera nueva()

10

En el primer caso, se puede obtener el mismo bloque de memoria de nuevo, pero no hay certeza de que .

En el segundo caso, ya que no ha liberado la memoria, hay una certeza de que obtendrá un bloque de memoria diferente en una dirección diferente. Hay recolectores de basura de C++. Si usó uno de estos, es concebible que el recolector de basura se ejecute entre el momento en que eliminó el puntero (para que ya no tenga acceso al bloque de memoria asignado previamente) y solicite una asignación nuevamente. En tal caso, podría obtener el mismo bloque de memoria nuevamente. Por supuesto, sin un recolector de basura, solo estás perdiendo memoria, por lo que no puedes hacerlo en ningún caso.

2

Lo que está preguntando es totalmente indefinido (según el estándar C/C++) y dependería de la implementación.

debería ser fácil para usted probar esto con su versión del compilador.

Lo que debe tener en cuenta es que nunca dependerá del resultado de este comportamiento, ya que puede cambiar en cualquier momento/con cualquier sistema operativo/incluso una actualización de su compilador.

En cuanto a lo que creo que podría suceder, obtendrías la misma dirección más probable, A MENOS QUE tengas otros hilos en tu programa que también estén asignados durante el mismo tiempo. Pero incluso entonces podría obtener la misma dirección, si la implementación particular de malloc de su compilador decide usar diferentes montones para diferentes subprocesos (que es mejor en términos de perf)

Cuestiones relacionadas