elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Punteros en estructuras
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Punteros en estructuras  (Leído 980 veces)
Desiresportal

Desconectado Desconectado

Mensajes: 57


Ver Perfil
Punteros en estructuras
« en: 31 Octubre 2019, 18:27 pm »

Estoy desarrollando alguna cosilla y utilizo una estructura similar a la siguiente para almacenar y manejar datos en binario.

Código
  1. struct datos {
  2. void *data;
  3. unsigned int length;
  4.  
  5. datos();
  6. void operator=(datos rDatos);
  7. ~datos();
  8. }
  9.  
  10. datos::datos() {
  11. data = NULL;
  12. length = 0;
  13. }
  14.  
  15. void datos::operator=(datos rDatos) {
  16. if (rDatos.length > 0 && rDatos.data != NULL) {
  17. length = rDatos.length;
  18. data = new unsigned char[length];
  19. if (data != NULL) {
  20. for (unsigned int a=0; a<length; a++) {
  21. ((unsigned char *)data)[a] = ((unsigned char *)rDatos.data)[a];
  22. }
  23. }
  24. }
  25. }
  26.  
  27. datos::~datos() {
  28. if (data != NULL) {
  29. delete[] (unsigned char *)data;
  30. }
  31. }
  32.  

Si hago algo como lo siguiente, se me cierra el programa con un error.

Código
  1. datos miVariable;
  2.  
  3. // Despues de ponerle datos a la variable....
  4.  
  5. miFuncion(miVariable);
  6.  

El caso es que he visto que el problema desaparece cuando el destructor de la estructura no elimina el buffer de datos. Y eso me va a llevar inevitablemente a llenar la memoria. O sino, me lleva a estar pendiente de liberar la memoria en cada programa que haga uso de mi pequeña libreria.

¿Porque ocurre esto? ¿Como puedo hacer correctamente el operador de copia y el destructor de la estructura para manejarlo como una variable mas? (O al menos como un string, por ejemplo)

Muchas gracias por adelantado.


En línea

ThunderCls


Desconectado Desconectado

Mensajes: 454


Coder | Reverser | Gamer


Ver Perfil WWW
Re: Punteros en estructuras
« Respuesta #1 en: 31 Octubre 2019, 20:08 pm »

Si no me equivoco el error que obtienes es al hacer un double "delete" sobre la misma memoria dinamica. Primero tu sobrecarga del operador de asignacion no deberia trabajar con copias de los objectos sino con referencias:

Código
  1. void datos::operator=(datos rDatos){}

deberia ser

Código
  1. void datos::operator=(const datos &rDatos){}

Tambien te aconsejaria que para poder usar asignaciones en cadena modifiques tu funcion a

Código
  1. datos &datos::operator=(const datos &rDatos)
  2. {
  3.    // ...
  4.    return *this;
  5. }

Luego, mi teoria de tu error es que al enviar tu estructura como parametro a la funcion lo estas haciendo por valor (por defecto), lo que crea una copia de los valores de dicha estructura en memoria al pasar a dicha funcion, cuando el tiempo de vida del parametro termina al salir de la funcion, se invoca a tu destructor sobre el mismo puntero de tu estructura original (ambos punteros apuntan a la misma memoria), luego al terminar tu funcion principal y concluir el ambito de tu variable de estructura original, se volvera a destruir el objeto llamando a tu destructor el cual intentara realizar otro "delete" sobre la misma posicion de memoria ya liberada antes, provocando una excepcion.

Posibles soluciones
Solucion 1: Intenta pasar tu estructura a la funcion por referencia y cuenta que tal:

Código
  1. miFuncion(miVariable);
  2.  
  3. void miFuncion(const datos &miVariable)
  4. {
  5.    datos miOtraVariable;
  6.  
  7.    miOtraVariable = miVariable;
  8. }

Solucion 2: Create un constructor de copia para tu estructura

Código
  1. datos::datos(const datos &copy)
  2. {
  3.    // tu copia aqui
  4. }
  5.  
Saludos


« Última modificación: 31 Octubre 2019, 20:24 pm por ThunderCls » En línea

-[ "…I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/
Loretz

Desconectado Desconectado

Mensajes: 115


Ver Perfil
Re: Punteros en estructuras
« Respuesta #2 en: 31 Octubre 2019, 22:20 pm »

Estoy desarrollando alguna cosilla y utilizo una estructura similar a la siguiente para almacenar y manejar datos en binario.

Código
  1. struct datos {
  2. void *data;
  3. unsigned int length;
  4.  
  5. datos();
  6. void operator=(datos rDatos);
  7. ~datos();
  8. }
  9.  

Si tu struct datos es responsable del manejo de un recurso de tipo void*, probablemente necesites usar templates en su lugar, o tener muy en claro el significado y funcionamiento de las funciones especiales de una clase. Y me da la impresión de que no es el caso.

En el destructor pones
Código:
delete[] (unsigned char *)data;
de modo que estás forzando a que data sea de tipo unsigned char*, ya no void*, lo mismo cada vez que necesitas hacer ese cast.

Tu problema no está (solamente) en el operador de asignación, sino en la idea misma de manejar un recurso con una clase C++ y, si no te molesta un consejo de tipo general, necesitas un buen libro y estudiar seriamente, no es preguntando sobre errores al azar que se aprende un lenguaje de programación complejo; realmente, con este sistema te tomará años convertirte en un programador mediocre.
En línea

Desiresportal

Desconectado Desconectado

Mensajes: 57


Ver Perfil
Re: Punteros en estructuras
« Respuesta #3 en: 1 Noviembre 2019, 13:15 pm »

Ya esta solucionado. Muchisimas gracias.

Resulta que al pasar la estructura a la funcion, independientemente de si lo hago por referencia o por copia, la funcion hacia uso del constructor de copia por defecto. Yo creia (y mal creido porque nunca hice pruebas ni encontré documentacion para entenderlo) que usaba el "=".

Citar
En el destructor pones
Código
  1. delete[] (unsigned char *)data;
de modo que estás forzando a que data sea de tipo unsigned char*, ya no void*, lo mismo cada vez que necesitas hacer ese cast.

Utilizo el tipo "void*" porque en esta estructura almaceno textos, enteros, decimales y puede que termine almacenando incluso estructuras. Es el tipo que veo cuando utilizo "fwrite()" y creía que era el apropiado para ir haciendo cast.

Ademas, tengo entendido que los cast son cosa del compilador y que en el programa resultante no existe carga extra por usarlo. ¿Me equivoco?

En cuanto a un libro, claro que me lo estudiaría de cabo a rabo. Aunque tienen varias pegas:
- Cuestan una pasta que no tengo (y en las bibliotecas publicas no hay o son de los que no profundizan nada)
- Lo explican todo de una forma muy dificil de digerir (incluso investigando un poco para arreglar este problema que ya he solucionado, no he encontrado nada que fuese facil de entender)
- Los mejores están en inglés y cualquier cosa que no sea codigo (a veces incluso el codigo) no la entiendo

En resumen:
Tema resuelto. Muchas gracias por la ayuda.
En línea

ThunderCls


Desconectado Desconectado

Mensajes: 454


Coder | Reverser | Gamer


Ver Perfil WWW
Re: Punteros en estructuras
« Respuesta #4 en: 1 Noviembre 2019, 19:56 pm »

Resulta que al pasar la estructura a la funcion, independientemente de si lo hago por referencia o por copia, la funcion hacia uso del constructor de copia por defecto. Yo creia (y mal creido porque nunca hice pruebas ni encontré documentacion para entenderlo) que usaba el "=".

En C++ siempre al pasar un objeto como parametro por valor a una funcion se invoca al constructor de copia de dicho objeto. Si el programador no tiene uno definido, el compilador genera un constructor de copia por defecto, el tema esta en que dicho constructor hace "shallow copy" y en este caso no es lo ideal por lo que ya explique anteriormente. Como no sabia lo que estabas intentando hacer ni las restricciones con las que estabas escribiendo tu codigo te di dos posibles soluciones, una de ellas era que te crearas tu propio constructor de copia usando "deep copy".

En cuanto a un libro, claro que me lo estudiaría de cabo a rabo. Aunque tienen varias pegas:
- Cuestan una pasta que no tengo (y en las bibliotecas publicas no hay o son de los que no profundizan nada)
- Lo explican todo de una forma muy dificil de digerir (incluso investigando un poco para arreglar este problema que ya he solucionado, no he encontrado nada que fuese facil de entender)
- Los mejores están en inglés y cualquier cosa que no sea codigo (a veces incluso el codigo) no la entiendo

- Si sabes usar un buscador en internet no necesitas pagar una fortuna por ningun libro
- Estos temas no son temas basicos o de principiantes, se supone que domines el lenguaje y varios conceptos llegado a este punto
- Te aconsejaria empezar a estudiar ingles si quieres dedicarte profesionalmente a esto o si deseas llegar a algun lado con la programacion y las tecnologias en general. Para todo lo demas esta Google Translator

En resumen:
Tema resuelto. Muchas gracias por la ayuda.

Me alegro. Suerte
En línea

-[ "…I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[C] Estructuras y punteros a funciones
Programación C/C++
Amadeo Magnus 1 5,356 Último mensaje 13 Octubre 2010, 15:05 pm
por Karman
estructuras punteros programacion c
Programación C/C++
adexrn 4 2,711 Último mensaje 9 Abril 2012, 10:10 am
por adexrn
Punteros a estructuras...???
Programación C/C++
Ja_90 4 1,601 Último mensaje 11 Noviembre 2014, 21:10 pm
por eferion
Estructuras con Punteros
Programación C/C++
jgonzalezo 1 919 Último mensaje 13 Abril 2015, 09:02 am
por eferion
Duda con estructuras y punteros
Programación C/C++
Miguel2097 4 1,565 Último mensaje 12 Diciembre 2016, 07:57 am
por Miguel2097
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines