Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - kafok

#11
Creo que se lo que pasa....

1) No se usar Application Verifier: Si, descargue el sdk de depuracion de windows cuando me lo dijo. He estado utilizando el WinDbg, y he estado intentando comprender el Application Verifier pero no soy capaz... haber cojo la aplicacion cargo mi programa y selecciono los test en la derecha y pulso save. Despues, ¿Usa el depurador de mi IDE, o como va eso?

2) Creo que se donde esta el problema: Me imagino que al hacer new y tenerlo sobrescrito para que guarde la memoria en el heap que le diga, los atributos de mis clases que no sean punteros se guardaran en dicho heap, pero ¿y cuando no uso new para inicializar el objeto?¿Donde se guarda ese atributo? Creo que ese es el problema, que se guarda donde no debe.

Entonces, si fuera ese el problema podria solucionarlo creando los atributos de forma dinamica, pero para el atributo que me da problemas uso una clase del std, string. Entonces ahora me surgen las siguientes dudas:

   -¿Como asigno al heap que yo quiera una clase de la que puedo sobrescribir el operador new? Es decir, ¿como guardo un objeto string en mi heap?

   -Si declarara el resto de atributos de mis clase a partir de punteros y los inicializara en el constructor y liberara en el destructor, si declaro una variable "estatica", como yo las llamo, de esa clase, al finalizar el ambito de esa varible ¿Se llamaria al destructor y liberaria esa memoria asignada o se liberara al finalizar el programa?

   -Y por ultimo, ya por curiosidad, una variable que no es un puntero, es decir, que no se inicializa con new ¿Como se llama eso? Yo las llamo inicializadas estaticamente, porque de otra forma es dinamicanmete, pero no se la terminologia real  :P
#12
Vamos a ver, antes de meterte en multi-thread, que en windows tienes aqui la documentacion (en ingles): http://msdn.microsoft.com/en-us/library/windows/desktop/ms684852(v=vs.85).aspx  Debes tener clara una cosa, en un juego vamos a tener un codigo ejecutandose en un bucle. En ese bucle cada iteraccion se considera que es un frame o una imagen a mostrar por pantalla. Cada iteraccion actualizara los estados los objetos de la escena entre otras cosas y por ultimo las pintara. Sigue el siguiente orden:
    Bucle:
        Actualizar fisica
        Actualiar pantalla (pintar)
    fin-bucle

-Actualizar pantalla: esta claro lo que es, simplemente pinta los objetos segun su estado (posicines, tamaños...)

-Actualizar fisica: esto es un poco mas complejo, la fisica de un juego depende del juego y puede ser mas o menos compleja. Para mover al jugador en algun momento debes comprobar que se presiona la tecla para moverlo en cada direccion, si es asi desplazmos en el eje de coordenadas que correspondo tantas unidades como velocidad quieras que se mueva ese objeto*. Luego mueves a los enemigos segun las condiciones que rijas tú, y despues comprueba si chocan. Despues de todas esta comprobaciones tienes que tener los objetos actualizados (en posicion, por ejemplo) y listos para ser pintados.

Al ser pintados me refiero que imprimas por consola el caracter/texto en la posicion que tengas, porque veo que es una simple aplicacion de consola (he hablado lo mas generico que pude, los juegos 3d con graficazos tambien funcionan asi)


*el tema velocidad dependera de la velocidad del ordenador, una velocidad 10 puede ir muy lento en un ordenador antiguo y demasiado rapido en un ordenador bueno. Para eso existen tecnicas complejas como el tiempo delta, o si es un juego que no consume recursos como es tu caso limitar a un numero cualquiera las iteracciones de tu bucle, pero ya te digo este tema es algo complejo
#13
Ahora tengo otro problema... he rediseñado mi proyecto de nuevo, los heap ya son correctos... pero... cuando asigno estaticamente memoria (es decir, en variables y no punteros, no se como se llama exactamente eso) me sigue dando problemas de violacion de acceso.

Mi clase tiene unos pocos de constructores, los cuales estoy testeando. Lo hice declarando un array para tener las multiples variables que cree bien situadas tal que asi:

Código (cpp) [Seleccionar]
MiClase clase[64];

Eso me tira error al finalizar el programa. Lo siguiente me da error cuando creo una variable desde el constructor tal que:

Código (cpp) [Seleccionar]
MiClase *clase = new MiClase[64];

Es decir, que en el momento que hago:

Código (cpp) [Seleccionar]
clase[0] = MiClase(1.0f)    //Por ejemplo

Crashea con el mismo error. Solo funciona de forma "estatica" (como yo lo llamo) si son variables independientes, es decir, no arrays.

Mi duda ahora es, tengo alguna limitacion para asignar a este tipo de variables desde una dll? de ser asi, ¿Como limito al usuario para que solo pueda usar new para crear objetos (no de forma "estatica")? Bueno, lo mismo es que yo este haciendo algo mal y no tengo ningun tipo de limitaciones  :-X
#14
Entonces, si sobrecargo el new y delete y utilizo el GetProcessHeap() por ejemplo, para asignar la memoria y liberarla, aunque llame a new desde el exe podre liberarlo desde el dll, y viceversa? De esa forma, me ahorraria todos los poblemas que me han surgido asignando memoria. Y si creo un heap para la dll seria exactamente igual solo que podria personalizar algunas cosas no?

Muchas gracias, me estas ayudando un monton
#15
Perdon por tardar en responder, he estado ocupado con los estudios  :-(

He estado haciendo mil pruebas, haber como reacciona las dll a algunas situaciones. Quiero destacar que mi dll es cargada estaticamente. He probado new y delete en distinto sitios (tanto en el exe como en la dll) y aunque han sido inicializadas en un sitio y liberado en otro la aplicacion no presento en ningún momento anomalias, funcionó bien, se creo y liberó memoria correctamente aun siendo declarados en distintos heaps. En la documentacion de windows solo nos ofrecen la funcion GetProcessHeap() que llamada desde la dll y el exe devuelve el mismo valor, porque es el mismo proceso. Pero no hay nada relacionado con el heap de cada modulo (el heap del exe y el de la dll) lo que da a entender que cada proceso tiene su propio heap, y este es compartido por la dll y el exe. Aqui hay una contradiccion, ¿Qué he dejado pasar por alto para haber obtenido estos resultados?

He leido que si sobrecargo los operadores new y delete y customizo la asignacion de memoria en un heap que haya creado o:

Código (cpp) [Seleccionar]
HeapAlloc(GetProcessHeap(), 0, size);

para el heap del proceso me curo en salud porque digo exactamente donde se guarda, pero... Sí guardo en un heap que no tengo acceso, ¿La aplicacion crashearia? Es decir, si estoy accediendo al heap del proceso, si no tenia permisos para borrar nada creado alli tampoco los tengo para crearlo, digo yo.

Por favor, que alguien arregle las barbaridades que estoy soltando
#16
Haber estuve leyendo y estudiando los links. Yo sabia que los programas utilizaban un espacio de memoria especial para la asignacion dinamica, vamos que eso es el heap. Pero vamos, entonces cada modulo tiene un heap distinto? Es decir, si cargo una dll todos los new dentro de los metodos se crearan en su heap y los new de mis programas en su propio heap? y el heap de la dll es compartido por todas las aplicaciones que utilicen la dll?

Entonces ¿Que limitaciones tengo al usar memoria dinamica al usar una dll? No me quedo muy claro en esas paginas.

Tu pregunta: los new los llamo desde la aplicacion y los delete desde la dll, aunque eso puede cambiar, porque esta pensado que los delete que no diga yo, los haga la dll al final, aunque de momento solo lo hace la dll.

Otra cuestion: Lo que yo tengo entendio es que la memoria que no liberes se queda como basura en el sistema hasta que reinicies, eso es lo que tengo entendido como memory leak. Pero tu que dices, que la memoria que no haya liberado la libera el sistema operativo cuando termina el programa? es decir, que la memoria que se libere tiene que ser liberada en el momento en el que deja de utilizarse, que si se elimina toda al final del programa es trabajar de mas porque el sistema operativo ya los hace?

Otra vez, muchas gracias por tu tiempo
#17
Haber, creo un objeto de mi clase con new desde el codigo de mi programa, vamos que no esta llamado desde ningun metodo ni nada por el estilo, el codigo seria tal que asi:

Código (cpp) [Seleccionar]
MiClase *c = new MiClase();

He de decir que new y delete son sobrecargados en una clase padre que llame Object y que debe heredarse en todas las clases hijas que quieran implementar esto, es decir "MiClase" es hija de Object. No se si esa informacion es de interes, pero la cuento por si acaso.

La intencion de esto es que pueda dejar sin liberar la memoria que yo quiera y luego cuando copile se me informe de que hay memoria no liberada que libera otra clase que es la que contiene el set. Esta clase es un singleton y tiene varios metodos entre ellos añadir y eleminar elementos del set, y uno en especial que recorre el set eleminando sus elementos y llamando al delete del objeto. Este metodo esta pensado para llamarlo al final del programa y que lo que no se haya liberado (que siga en el set) lo elimine y lo imprima por pantalla.

Si llamas al delete desde el codigo de la aplicacion se elimina el elemento del set. En la implementacion de esto cuando se llama a delete este llama a "erase" y "erase" a delete, lo se, ese problema de recursividad esta solucionado.

Entonces delete es llamado desde ese metodo y desde la aplicacion, es decir los que no llame la aplicacion los llamara el metodo. El problema que ambos tienen que hacer un al metodo erase de set del std y es esa linea la que falla.

Ahora, te pregunto una cosa, lo que he encontrado en internet todos dicen que es que el set se hayan rotos los punteros interno que usa el arbol binario de la implementacion (o por lo menos creo que funciona asi), y tu me has hablado algo de heaps, no se... me da que puede haber hay un hilo por donde tirar, ¿Que son heaps? Detallame que es lo que puede pasar con ellos.

PD: ahora espero haberte hecho una descripcion mas profunda del problema y que a si podamos llegar a una solucion



Ante todo, muchisimas gracias por la ayuda, no se que hubiera hecho yo solo...  :huh:
#18
Programación C/C++ / Re: Ayuda en un programilla
14 Noviembre 2014, 02:36 AM
Haber con system esta ejecutando ya comandos del cmd, es decir si en cmd escribes cd lo que sea y en system le pones ese mismo texto hara lo mismo
#19
Bueno llevo unos dias investigando a tope, he cambiado de IDE ya que la ultima me estaba dando muchos problemas y tambien llevo estos dias testeando las nuevas cosas. Pues resulta que cuando copilo en este nuevo entorno resulta que se rompe pero en el delete no en el new, y digo yo ¿Por que se rompe cuando llamo a los metodos desde una dll (importada estaticamente) y no si cojo el mismo codigo y lo copilo dentro de un proyecto independiente?

[b]Nota:[/b] he sobrecargado los operadores new y delete para guardar los punteros de los nuevos objeto en un set de la api std. Esto lo hice como una especie de recolector de basura con el fin de que me avisara si se me olvida un delete porque me hace mas los test de las clases

Despues de mucho tocar el codigo, depurar, etc... resulta que es que al borrar un elemento del set es cuando rompe, new y delete funcionan bien, solo falla si quito del set el elemento que reciba delete. Pero claro, el codigo esta bien pero al aislarlo en una dll y cargarlo desde otro proyecto sin ni siquiera tocar una linea de codigo me desconcierta, ¿Por que falla en un sitio si y en otro no (reitero)?

PD: Puede que depurar esto sea facil, pero es la primera vez que me enfrento a algo que hay que mirar en tan bajo nivel :(

Por cierto, el debbuger de ahora me dice que el procesador tira la señal SIGSEV, por si sirve de algo
#20
Cita de: kub0x en 10 Noviembre 2014, 04:42 AM
Estoy con Eternal, no parece gran cosa...
Ya se que sera al final una tonteria... pero es que nunca he tenido que utililar herramientas tan complejas para depurar.

Bueno kub0x he estado toda la tarde trasteando, googleando, leyendo la documentacion de windows... bueno he estado tambien testeando con programas que fallaban a posta y recogiendo las excepciones y bueno este es el codigo que he empleado para recojerlas:

Código (cpp) [Seleccionar]
LONG WINAPI MyUnhandledExceptionFilter(_EXCEPTION_POINTERS *e)
{
    cout << e->ExceptionRecord->ExceptionAddress << endl;
    cout << e->ExceptionRecord->ExceptionCode << endl;
    cout << e->ExceptionRecord->ExceptionFlags << endl;
    cout << e->ExceptionRecord->ExceptionInformation << endl;
    cout << e->ExceptionRecord->NumberParameters << endl;
   
    system("pause");

    return EXCEPTION_EXECUTE_HANDLER;
}


Haber el comando "pause" se debe a que el codigo lo tengo que ejecutar varias veces porque no siempre crashea, es depende como le pille, aunque la mayotia de veces si crashea y para dificultar las cosas cuando se esta depurando no crashea, vamos que mi propio codigo me esta vacilando como quien dice -,-"

Bueno la salida es esta:
Código (dos) [Seleccionar]
0x77340b8f
3221225477
0
0x28f6b0
2
Presione una tecla para continur...


Bueno, la segunda linea es la que he visto interesante, 3221225477 que en hx es 0xC0000005 y segun winbase.h equivale al codigo EXCEPTION_ACCESS_VIOLATION, es decir el mismo codigo que cuando llamo al metodo de un objeto puntero que apunta a NULL. Aun asi he buscado en internet lo referente a este error y no viene nada en ningun lado...

¿Como averiguo que esta pasando?¿Vale ya se que excepcion salta y ahora qué si no se que la provoca?