Хрестоматия по программированию на Си в Unix


   игровой клуб вулкан играть             

Возможно также отслеживание диапазона адресов,


Пример 10


/* Проблема: позволить делать вызов free(ptr) * на данные, не отводившиеся malloc()-ом. * Решение: вести список всех данных, * отведенных malloc()ом. * Возможно также отслеживание диапазона адресов, * но последнее является машинно-зависимым решением. * * При большом количестве файлов эта программа - неплохой тест * производительности машины! */ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _cell { void *addr; struct _cell *next; } Cell;
typedef struct _entry { int length; int used; Cell *list; } Entry;
/* Хэшированная таблица */ #define NENTRIES 64 Entry aTab[NENTRIES];
/* Хэш-функция от адреса */ int aHash(void *addr){ unsigned long x = (unsigned long) addr; x >>= 3; /* деление на 8, так как адреса из malloc() обычно четные, поскольку выровнены на границу double */ return(x % NENTRIES); /* Тут к месту напомнить, что вычисление остатка от деления на степень двойки * можно соптимизировать: * x % (2**N) = x & 0b0001.....1 (N двоичных единиц) * К примеру, x % 64 = x & 0x3F; (6-ая степень двойки) */ }
/* Выделить память, записать адрес в таблицу */ void *aCalloc(int n, int m){ void *ptr = calloc(n, m); Entry *ep = &aTab[ aHash(ptr) ]; Cell *p;
for(p=ep->list; p; p=p->next) if(p->addr == NULL){ /* Свободная ячейка: переиспользовать */ p->addr = ptr; ep->used++; return ptr; } /* Нет свободных, завести новую */ p = (Cell *) calloc(1, sizeof(Cell)); p->addr = ptr; p->next = ep->list; ep->list = p; ep->length++; ep->used++; return ptr; }
/* Освободить память */ int aFree(void *ptr){ Entry *ep = &aTab[ aHash(ptr) ]; Cell *p;
for(p=ep->list; p; p=p->next) if(p->addr == ptr){ free(ptr); p->addr = NULL; /* Ячейка не удаляется, но метится как свободная */ ep->used--; return 1; } /* Нет, такой указатель не отводился. * Не делать free() */ return 0; }
/* Выдать статистику об использовании хэша */ void aStat(){ int i; int len_all; int used_all;

Содержание  Назад  Вперед