Foro con Clase C/C++

Dos punteros, una zona de memoria, ¿qué ocurre exactamente?

shorosky

Nº de hilos:1

Nº de mensajes:2

domingo, 31 de enero de 2021


En el capítulo 35, correspondiente con la sobrecarga de operadores dentro de las clases, se expone un ejemplo del problema que puede suponer no sobrecargar el operador de igualdad cuando hay punteros de por medio.
Cuando se hace la copia de un objeto, la copia por defecto copiará el puntero haciendo que apunte a la misma dirección de memoria que el objeto que se pasa como argumento para realizar la copia. Cuando debería hacer una copia de toda la zona de memoria, no del puntero.
El problema viene a la hora de destruir un objeto, deja al otro apuntando a una zona de memoria que ya ha sido liberada.

Copio y pego el texto donde me asaltan las dudas:
Lo que realmente copiamos no es la cadena, sino el puntero. Ahora los dos punteros de las cadenas C1 y C2 están apuntando a la misma dirección. ¿Qué pasará cuando destruyamos los objetos? Al destruir C1 se intentará liberar la memoria de su puntero cadena, y al destruir C2 también, pero ambos punteros apuntan a la misma dirección y el valor original del puntero de C2 se ha perdido, por lo que su memoria no puede ser liberada.

¿Qué quiere decir que la memoria de C2 no puede ser liberada?
Por lo que entiendo, la zona de C2 ha sido liberada al destruir C1, y C2 se queda apuntando a una zona que no es segura, pues en cualquier momento puede ser ocupada por nuevos datos. Creo que no llego a comprender bien cómo se hace la gestión de memoria.

Gracias.
Un saludo.

Tema cerrado

Salvador Pozo

Nº de hilos:0

Nº de mensajes:25

miércoles, 3 de febrero de 2021


Hola:

> En el capítulo 35, correspondiente con la sobrecarga de operadores dentro de las clases, se expone un ejemplo del problema que 
> puede suponer no sobrecargar el operador de igualdad cuando hay punteros de por medio.

Cuidado de no confundir el operador de asignación (=) con el de igualdad (==). No es lo mismo, aunque usen el mismo símbolo.

> ¿Qué quiere decir que la memoria de C2 no puede ser liberada?

El sistema operativo puede gestionar la memoria de modo que si el programa intenta liberar una memoria que no ha sido obtenida por él, se producen errores de ejecución. En cualquier caso, aunque pudiera serlo sin producir errores, no debe serlo.
Por otra parte, la destrucción de los dos objetos no tiene por qué producirse en ese orden, ni de forma consecutiva, ni siquiera tiene que tratarse sólo de dos objetos, podría ser un array de objetos, o de objetos de diferentes clases que usaran memoria dinámica. 
Por ejemplo, nuestro programa podría destruir primero el objeto C2, a continuación crear un nuevo objeto C3, que podría ubicarse en la memoria recién liberada, corrompiendo el contenido de C1. Más tarde podemos destruir el objeto C1, que comparte al menos una parte de su memoria con C3, con lo que perdemos el contenido de C3.
La idea de fondo es que puede que lo que nosotros queremos conseguir con un programa no sea exactamente lo que estamos programando. Con los punteros siempre hay que ser muy cuidadoso.
 
> Por lo que entiendo, la zona de C2 ha sido liberada al destruir C1, y C2 se queda apuntando a una zona que no es segura, 
> pues en cualquier momento puede ser ocupada por nuevos datos. Creo que no llego a comprender bien cómo se hace la 
> gestión de memoria.

En lenguajes como C o C++ la gestión de memoria la hace el programador. Gran parte de la potencia de estos lenguajes es que no proporcionan control de alto nivel sobre la memoria. Esto es una ventaja en cuanto a prestaciones de velocidad de ejecución y gestión de recursos. Los programas escritos en C o C++ son más rápidos y precisan menos memoria que los escritos en otros lenguajes. El inconveniente es que nos obliga a ser muy cuidadosos en la gestión de los recursos.
Las últimas versiones del compilador de C++ proporcionan nuevas herramientas, como los punteros inteligentes, que nos ayudan a hacer mejor esa gestión, pero eso no implica que debamos ser menos cuidadosos.

Gracias.
Un saludo.

Tema cerrado