Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Std::vector Y Punteros

Iniciado por DraKKaR, 09 de Enero de 2004, 11:38:43 AM

« anterior - próximo »

DraKKaR

 Estoy usando la std::vector para almacenar un vector de punteros a un objeto:

std::vector vector_mallas;

El problema es que usando el devpartner me ha detectado muchos errores del tipo: Dangling Pointer (es decir, se intenta acceder a una posición de memoria que ya ha sido liberada) usando la std::vector con punteros.  He estado inspeccionando el código fuente de la std::vector y sí que parece que libere memoria de sus componentes como le conviene.

La pregunta es: ¿Es bueno hacer un std::vector de punteros a algo?

MChiz

 Yo lo he hecho mil veces y no hay ningun tipo de problema.

CoLSoN2

Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

Zaelsius

 Tanto DevPartner como Purify se equivocan siempre con la STL , así que don't worry.  ;)

Para que te quedes más tranquilo copio unas lineas de la FAQ de la SGI STL(igualmente aplicable a cualquier implementación de STL):

Citar
Why am I getting uninitialized memory reads from PurifyTM?
We believe that the uninitialized memory read (UMR) messages in STL data structures are artifacts and can be ignored.

Why does Bounds CheckerTM say that I have memory leaks?
This is not an STL bug. It is an artifact of certain kinds of leak detectors.

Bounds Checker es el antiguo nombre del componente de detección de errores de DevPartner.

DraKKaR

 Vale, me quedo más tranquilo.

Gracias, ya me estaba rallando con esos errores.
Por cierto, ya que estamos... ¿Como haceis vosotros para pillar esos fallos extraños de ejecución que no tiene una explicación aparente?

Zaelsius

 ¿A qué fallos te refieres? En Visual C++, pues modo debug, F5, y 'palante'  

DraKKaR

 El problema lo tengo con un delete sobre un puntero a una clase de mi motor reservado con new.
Al hacer el delete me da un error de:

User breakpoint called from code at 0x77f65a58

en el stack de llamadas veo que al ahcer el delete la ejecución se ha metido por el fichero dbgheap.c llamando a la función _free_dbg(void*,int). El error lo ha dado en la siguiente linea de esa función:

       /*
        * If this ASSERT fails, a bad pointer has been passed in. It may be
        * totally bogus, or it may have been allocated from another heap.
        * The pointer MUST come from the 'local' heap.
        */
       _ASSERTE(_CrtIsValidHeapPointer(pUserData));

¿Alguna idea de que peude pasar?

Zaelsius

 Pues mirando eso que has puesto, sólo se me ocurre que el new y el delete se hagan desde módulos diferentes, tal vez desde aplicación/dll  :huh:  y que teniendo zonas de memoria distintas sea esa la causa del error al hacer delete.

ethernet

 Mucho cuidado con los punteros. Posiblemente estes intentando hacer un delete sobre un puntero que ya ha sido liberado. Para evitar estas mierdas lo mejor es usar ref count.

saludos

Kriller

 Otra forma de evitar hacer un delete de un puntero ya liberado es poniendo siempre el puntero a NULL justo después de hacer el delete (con una macro por ejemplo). El delete no hace nada cuando se le pasa NULL así que el segundo delete no tendría ningún efecto.

Personalmente esto me gusta más que el contador de referencias.

ethernet

 A mi eso me parece bastante mas cutre, mas q nada porque no sirve para nada en este caso (*) y lo q es mas importante y para lo q sirve tener ref count: Hasta que todas las referencias  a esa instancia no hayan desaparecido no se libera el objeto. Con esa macro lo unico que haces es evitar petes extraños.  No son comparables

(*)

int *p,*o=new int;
p=o;
delete o; o = 0;
*p=1000; // petada;


Kriller

 Eso es verdad, no son comparables. Ahora bien, que lo de poner un puntero a NULL después de liberarlo es cutre no estoy en absoluto de acuerdo, es todo lo contrario. De esa manera siempre sabes con total certeza que si un puntero es distinto de NULL, entonces apunta a algo válido.

Lo del contador de referencias creo que no es necesario en la mayoría de los casos y que con el otro método es completamente suficiente (vamos, a mí me va muy bien). Eso sí, te obliga a ser muy disciplinado y riguroso con cuándo y dónde reservas/liberas pero, ¿no hay que serlo también con el resto?  :P

Saludos.

DraKKaR

 Gracias a todos por responder.

ZaelsiuS: El new y el delete los hago desde el mismo módulo, solo que en funciones distintas.

ethernet: Me gusta eso del ref count, pero como implementarlo? ¿sobrecargando el operator= para los punterios?  :blink:

Además hay un par de cosas que no os he dicho:
- Este fallo solo me pasa en modo Debug (lógico ya que el error me lo da dentro de un ASSERTE como os he copiado arriba), en modo Release no me da ningún problema (como odio cuando en release va bien y en debug no y viceversa v.v)

- Antes de hacer el delete observo el contenido del puntero en el watch view y no parece un sector corrupto, todos sus datos son perfectamente válidos.

ethernet

 drakar -> mira la clase smart_ptr

Kriller->

has visto el ejemplo q te he puesto?

En ese ejemplo se ve q por mucho NULL q pongas la aplicacion petara igual, sin embargo con ref count no petara.  Y es que hay algun problema para el progrmador cuando solo tenems un puntero a la zona de memoria? el problema viene cuando tenemos varios y en ese caso la macro esa no sirve para absolutamente nada XD.

Ademas, es mucho menos cutre sobrecargar delete y delete[] que usar macros de mierda.

saludos

seryu

Cita de: "ethernet"Ademas, es mucho menos cutre sobrecargar delete y delete[] que usar macros de mierda.
pobres macros, ni qe fuera mordiendo a la gente






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.