Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





saber si un puntero apunta a una zona de memoria yareservada

Iniciado por Loover, 11 de Diciembre de 2002, 01:32:37 AM

« anterior - próximo »

Loover

                                Supongamos un puntero a una estructura:

estructura *ptrEstructura;

Reservamos espacio:
ptrEstructura = new estructura;


Ahora podré hacer cosas cómo:
ptrEstructura->x = 0; (perteneciendo x a la estructura)

Sin embargo, si no hubiera reservado espacio, el programa habría petado lógicamente.
Ahora bien, que pasa cuándo no sé si el puntero que me llega tiene reservado espacio... es decir, me llega ptrEstructura, pero no sé si se ha hecho un new o un malloc o lo que sea asignándoselo a dicho puntero.
¿Hay alguna función parecida a esta?

bool IfValidPtr (ptrEstructura)

Es decir, que me diga si el puntero apunta a una zona de memoria q ya tenga reservada memoria de su tipo y que en caso contrario devuelva 0.                                
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Nekorash

                                Yo lo que hago es nada más crear un puntero le asigno NULL. Así, cuando quiero comprobar si apunta a algún sitio símplemente compruebo que sea distinto de NULL, con lo que sabré que ya he apuntado ese puntero en alguna parte del programa. Ahora bien, desconozco si existe alguna función como la que dices.                                

Loover

                                Ya, pero lo que pasa es que parto de la idea que el puntero que me llega PUEDE estar apuntando a una zona no válida.
Es que estoy haciendo una libreria y puede ser que al usuario le de por hacer así:

Entidad.superficie = imagen1;

Sin haber hecho antes algo como:

LOV_Surface *imagen1 = LOV_LoadImage ("prueba.tga", LOV_ALPHA);

Si hace sólo esto: LOV_Surface *imagen1;
Y luego la asigna a la entidad... logicamente petará, y me gustaría saber si hay alguna forma de preveer esos errores que puede cometer el usuario.

Un saludo                                
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

synchrnzr

                                No es normal en una librería prever todos los posibles errores del usuario ¿Piensas que al hacer un delete() o un free() la librería estándar del C comprueba si el apuntador apunta a una posición reservada? (si la respuesta es sí, prueba a hacer delete(NULL) y verás como mola XDDD)

Yo en tu lugar no lo comprobaría.

Por un lado, aunque puede que no sea tan difícil saber si el área a la que apunta un apuntador pertenece al área reservada por la misma aplicación, lo seguro es que el tiempo consumido en la comprobación puede ser relativamente alto. Si tu intención es una librería de alto rendimiento, lo lógico es evitar al máximo estas comprobaciones de parámetros. El usuario de la librería se supone que es programador y es suficientemente listo como para no pasar parámetros incorrectos. Seguro que valora más que la función sea rápida y eficiente que no que compruebe minuciosamente si los parámetros que le pasas son correctos.

Por otro lado, es normal imponer ciertas restricciones al usuario de la librería siempre y cuando estén documentadas. Aunque el caso que pones de ejemplo creo que no haría falta ni documentarlo, basta con que en la documentación digas que TuFuncion(t *parametro) debe contener un apuntador a un parámetro de tipo t y se entiende que el usuario debe pasarle un apuntador válido. Si lo hace mal, yo que ti mostraría un mensaje de error tipo User error: replace user and press any key to continue... :X9:

No te canses :D

Sync                                

Loover

                                Pues sí, pasaré del tema :( Jo, quería que fuera 100% estable. Pero habrá formas de petarla :(                                
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Repoker

                                Para comprobar si un puntero tiene "algo" no bastaría con hacer un assert puntero != NULL ?                                

Loover

                                No tengo ni idea de como funciona ASSERT y eso que he leido varias veces que es muy últil. ¿Puedes decirme una direccion en la que venga explicada?                                
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

synchrnzr

                                Los punteros no se inicializan a NULL por defecto, alguien los tiene que poner a NULL. En teoría cualquier variable no inicializada contiene datos aleatorios.

Sync                                

Repoker

                                Bueno, entonces para comprobarlo bastaría con hacer un assert de alguna operacion del objeto apuntado por el puntero, algo así como

assert( p -> id != 0 );

-o-

assert(p -> name != NULL);

No se .. a lo mejor se puede hacer alguna chapucilla de estas :P
Si el assert sale mal, pues seguramente es que el objeto apuntado no esta inicializado, o está vacío .. bueno, es bastante chapuza.                                

Loover

                                Pero repoker, eso no sirve. Puede que el puntero tenga un valor que apunte a una zona no reservada.

Mira una forma simple de hacerlo:

LOV_Surface *superfice = (LOV_Surface *) 45;

Ahora surface apunta a la zona de memoria 45, pero si intento hacer algo como surface.width = 0; lógicamente petará.

Lo que me gustaría saber es lo que he preguntado antes, si apunta a una zona que tenga reservada memoria de ese tipo.
Pero bueno, da igual, seguire el consejo de sync y no preveeré esos casos.                                
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

synchrnzr

                                Repoker: así puedes provocar un fallo de protección general bien fácilmente. De todas formas, piensa que si tienes la mala suerte que el contenido aleatorio del puntero apunta a tu área de datos, entonces te estarás jodiendo el programa y a la vez ejecutando código aleatorio lo cual es algo un poco peligroso... :loco:

Y las probabilidades que te pase eso son tanto más grandes cuanta más memoria ocupa tu programa. Mralo por otro lado, también puedes sobreescribirte el área de datos, datos que supones que son correctos. Imagínate que cambias un dato por 0 que era denominador de una fracción... ¡Division by zero rules!

En fin... las posibilidades son infinitas :D

Sync                                

Malandrin

                                Hola,

Yo haría lo que dice synchrnzr, no hacer comprobaciones y que sea el usuario el que esté al loro. Pero una forma de hacer lo que dices es ir almacenando los punteros válidos en una lista (p.e. sobrecargando el new y metiendo ahí la gestión), y luego cuando vayas a acceder a algún puntero mirar en la lista si ha sido creado correctamente. Esto es una mierda pq enlentece mucho al hacer las comprobaciones y ocupa sitio en memoria inutilmente.

Saludos.                                

Loover

                                Gracias a todos. Espero que la usen usuarios listos.  :ojo:                                
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

synchrnzr

                                Doy la razón a Malandrín completamente

Sync                                

CordayUK

                                puedes hacerte tu una funcion que llame a malloc y que inicialize toda la memoria a un valor, tipicamente se hace 0xAA por ejemplo.

inline void* miMemoryAlloc (unsigned long ulSize)
{
  void* p = malloc (ulSize);
  assert (p && "No hay memoria!");
  memset (p, 0xAA, ulSize);
}

cuando utilices un puntero a partir de entonces, antes de usarlo comprueba que vale 0xAA sino es que no esta reservado.

Otra cosa que puedes hacer es cuando reservas memoria en la funcion anterior, poner un valor fijo tanto en una posicion anterior como posterior del rango que reservas, a por ejemplo 0xAB

chequeando por este valor cuando escribas podras comprobar cuando alguien esta escribiendo mas de la cuenta, (por ejemplo escribo hasta que el indice sea menor o igual que el final, etc..)                                






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.