Guest User

new

a guest
May 17th, 2020
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.82 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h> //sbrk
  4.  
  5. void *malloc(unsigned);
  6. void *calloc(unsigned, size_t);
  7.  
  8. int main()
  9. {
  10.     char a[] = "string to copy";
  11.     char *b;
  12.     int *arr;
  13.  
  14.     b = (char *)malloc(strlen(a) + 1);
  15.     strcpy(b, a);
  16.     printf("%s\n", b);
  17.  
  18.     arr = (int *)calloc(10, sizeof(int));
  19.     for (int i = 0; i < 10; i++)
  20.         printf("%d ", arr[i]);
  21.     return 0;
  22. }
  23.  
  24. typedef long Align; //для выравнивания по границе long
  25. union header {      //заголовок блока
  26.     struct
  27.     {
  28.         union header *ptr; //указатель на следующий свободный блок
  29.         unsigned size;   //размер этого блока
  30.     } s;
  31.     Align x; //принудительное выравнивание блока
  32. };
  33. typedef union header Header;
  34.  
  35. static Header base;          //пустой список для начального запуска
  36. static Header *freep = NULL; //начало в списке свободных блоков
  37.  
  38. void *malloc(unsigned nbytes)
  39. {
  40.     Header *p, *prevp;
  41.     Header *morecore(unsigned);
  42.     unsigned nunits;
  43.  
  44.     nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
  45.     if ((prevp = freep) == NULL)
  46.     {                                       //списка свободной памяти еще нет
  47.         base.s.ptr = freep = prevp = &base; //структура с указателем на саму себя
  48.         base.s.size = 0;                    //и нулевым размером
  49.     }
  50.     for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr)
  51.     {
  52.         if (p->s.size >= nunits)
  53.         {                            //достаточно большой блок
  54.             if (p->s.size == nunits) //точно нужного размера
  55.                 prevp->s.ptr = p->s.ptr;
  56.             else
  57.             { //отрезаем хвостовую часть
  58.                 p->s.size -= nunits;
  59.                 p += p->s.size;
  60.                 p->s.size = nunits;
  61.             }
  62.             freep = prevp;
  63.             return (void *)(p + 1);
  64.         }
  65.         if (p == freep) //прошли полнвй цикл по списку
  66.             if ((p = morecore(nunits)) == NULL)
  67.                 return NULL; //больше памяти нет
  68.     }
  69. }
  70.  
  71. void *calloc(unsigned ncells, size_t cellsize)
  72. {
  73.     Header *p, *prevp;
  74.     Header *morecore(unsigned);
  75.     unsigned nunits;
  76.  
  77.     nunits = (ncells * cellsize + sizeof(Header) - 1) / sizeof(Header) + 1; //malloc: (nbytes + sizeof(Header)-1)/sizeof(Header)+1
  78.     if ((prevp = freep) == NULL)
  79.         base.s.ptr = freep = prevp = &base;
  80.     for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr)
  81.     {
  82.         if (p->s.size >= nunits)
  83.         {
  84.             if (p->s.size == nunits)
  85.                 prevp->s.ptr = p->s.ptr;
  86.             else
  87.             {
  88.                 p->s.size -= nunits;
  89.                 p += p->s.size;
  90.                 p->s.size = nunits;
  91.             }
  92.             freep = prevp;
  93.             /*заполнение блока памяти нулями*/
  94.             for (char *q = (char *)(p + 1); ncells-- > 0; q += cellsize)
  95.                 *q = 0;
  96.             return (void *)(p + 1);
  97.         }
  98.         if (p == freep)
  99.             if ((p = morecore(nunits)) == NULL)
  100.                 return NULL;
  101.     }
  102. }
  103.  
  104. #define NALLOC 1024
  105.  
  106. void free(void *);
  107.  
  108. /*morecore запрашивает не более NALLOC единиц памяти*/
  109. Header *morecore(unsigned nu)
  110. {
  111.     char *cp;
  112.     Header *up;
  113.  
  114.     if (nu < NALLOC)
  115.         nu = NALLOC;
  116.     cp = (char *)sbrk(nu * sizeof(Header)); //(char *) – специально для Cxx
  117.     if (cp == (char *)-1)                   //больше памяти нет
  118.         return NULL;
  119.     up = (Header *)cp;
  120.     up->s.size = nu;
  121.     free((void *)(up + 1));
  122.     return freep;
  123. }
  124.  
  125. void free(void *ap)
  126. {
  127.     Header *bp, *p;
  128.  
  129.     bp = (Header *)ap - 1; //указатель на заголовок блока
  130.     for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
  131.         if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
  132.             break; //освобождаем блок в начале или в конце
  133.     if (bp + bp->s.size == p->s.ptr)
  134.     {
  135.         bp->s.size += p->s.ptr->s.size; //слить с верхним соседом
  136.         bp->s.ptr = p->s.ptr->s.ptr;
  137.     }
  138.     else
  139.         bp->s.ptr = p->s.ptr;
  140.     if (p + p->s.size == bp)
  141.     {
  142.         p->s.size += bp->s.size;
  143.         p->s.ptr = bp->s.ptr; //слить с нижним соседом
  144.     }
  145.     else
  146.         p->s.ptr = bp;
  147.     freep = p;
  148. }
Advertisement
Add Comment
Please, Sign In to add comment