1 /* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
3 * Taller de Programación (75.42).
6 * Programa calculadora.
8 * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9 * Puede copiar, modificar y distribuir este programa bajo los términos de
10 * la licencia GPL (http://www.gnu.org/).
12 * Creado: sáb ago 30 20:08:45 ART 2003
25 * Lista interna a utilizar en memdebug_malloc() y memdebug_free().
27 static DLList* memdebug_list;
30 * FIXME la búsqueda se realiza de atrás hacia adelante para que sea más
31 * eficiente, ya que generalmente se borra primero la memoria que se pidió
34 bool memdebug_DLList_find(DLList* list, void* ptr) {
36 for (i = DLList_end(list); DLList_have_more(list); i = DLList_prev(list)) {
37 if (i->pointer == ptr) {
44 void memdebug_info_print(MemInfo* mi, FILE* fp) {
47 ltime = localtime(&(mi->time));
48 strftime(fecha, 30, "%c", ltime);
49 fprintf(fp, "| 0x%08X | %5u | %-30s | %-20s | %5u |\n",
50 (size_t)(mi->pointer),
57 void memdebug_list_print(FILE* fp) {
59 fprintf(fp, "+------------+-------+--------------------------------+"
60 "----------------------+-------+\n");
61 fprintf(fp, "| %-10s | %-5s | %-30s | %-20s | %-5s |\n",
67 fprintf(fp, "+------------+-------+--------------------------------+"
68 "----------------------+-------+\n");
69 for (mi = DLList_begin(memdebug_list);
70 DLList_have_more(memdebug_list);
71 mi = DLList_next(memdebug_list)) {
72 memdebug_info_print(mi, fp);
74 fprintf(fp, "+------------+-------+--------------------------------+"
75 "----------------------+-------+\n");
78 void* memdebug_malloc(size_t bytes, const char* fname, size_t fline) {
80 /* Si no está creada la lista global, la creo (o intento). */
82 memdebug_list = DLList_new();
83 /* Si no se puede crear la lista no reservo memoria, devuelvo NULL. */
86 fprintf(stderr, "%s: No se pudo crear la lista interna "
87 "(llamado desde %s, línea %i).\n",
88 __FILE__, fname, fline);
93 /* Intento reservar memoria pedida. */
95 /* Si se puedo reservar, creo un nuevo nodo y lo agrego a la lista. */
97 MemInfo* mi = MemInfo_new(ptr, bytes, fname, fline);
98 /* Si no se puede crear el nodo, devuelvo NULL. */
99 if (!mi || !DLList_push(memdebug_list, mi)) {
101 fprintf(stderr, "%s: No se pudo crear el nodo para 0x%X "
102 "(llamado desde %s, línea %u).\n",
103 __FILE__, (size_t)ptr, fname, fline);
111 void memdebug_free(void* ptr) {
112 /* Busca en la lista y de encontrarlo nos lo deja en el elemento actual. */
113 if (memdebug_DLList_find(memdebug_list, ptr)) {
114 /* Lo encontró, elimino el nodo actual. */
115 DLList_remove_current(memdebug_list);
118 fprintf(stderr, "%s: No se encontro el ptr 0x%X en la lista.\n",
119 __FILE__, (size_t)ptr);
122 /* Lo encuentre o no, trata de liberar la memoria. */
126 void memdebug_end(void) {
127 /* Si hay una lista. */
130 /* Imprimo la lista si hay algun elemento. */
131 if (!DLList_empty(memdebug_list)) {
132 memdebug_list_print(stderr);
134 /* Libero la memoria de cada elemento y cada puntero almacenado. */
135 while (!DLList_empty(memdebug_list)) {
136 mi = DLList_pop(memdebug_list);