fork download
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <unistd.h>
  4.  
  5. static char *start;
  6. static const int head = sizeof(uintptr_t);
  7.  
  8. static void dump() {
  9. char *p, *last = (char *)sbrk(0), *next;
  10. for (p = start; p && p < last; p = next) {
  11. uintptr_t sz = *(uintptr_t *)p;
  12. next = p + head + (sz & ~1);
  13. printf("* %p, %p - %p: %s %d\n",
  14. p, p + head, next - 1, sz & 1 ? "used" : "free", sz & ~1);
  15. }
  16. printf("==%p\n", last);
  17. }
  18.  
  19. void *mymalloc(uintptr_t size) {
  20. char *p, *last = (char *)sbrk(0), *next;
  21. if (!start) start = last;
  22. size = (size + head - 1) & ~(head - 1);
  23. for (p = start; p < last; p = next) {
  24. uintptr_t sz = *(uintptr_t *)p;
  25. next = p + head + (sz & ~1);
  26. if (!(sz & 1) && sz >= size) {
  27. if (sz > size)
  28. *(uintptr_t *)(p + head + size) = sz - size - head;
  29. break;
  30. }
  31. }
  32. if (p >= last) p = (char *)sbrk(head + size);
  33. *(uintptr_t *)p = size | 1;
  34. printf("mymalloc(%d) -> %p\n", size, p + head);
  35. dump();
  36. return p + head;
  37. }
  38.  
  39. void myfree(void *ptr) {
  40. char *p, *last = (char *)sbrk(0), *next;
  41. uintptr_t *h;
  42. printf("myfree(%p)\n", ptr);
  43. if (!ptr || !start) return;
  44. h = (uintptr_t *)(((char *)ptr) - head);
  45. for (p = start; p < last; p = next) {
  46. uintptr_t sz = *(uintptr_t *)p;
  47. if (!(sz & 1) && p + head + sz == (char *)h) {
  48. sz += head + (*h & ~1);
  49. h = (uintptr_t *)p;
  50. }
  51. sz &= ~1;
  52. next = p + head + sz;
  53. if (p == (char *)h) {
  54. if (next < last) {
  55. int nextsz = *(uintptr_t *)next;
  56. if (!(nextsz & 1)) sz += head + nextsz;
  57. }
  58. if (p + head + sz >= last) brk(p); else *h = sz;
  59. dump();
  60. return;
  61. }
  62. }
  63. }
  64.  
  65. int main(void) {
  66. void *p[4];
  67. dump();
  68. p[0] = mymalloc(8);
  69. p[1] = mymalloc(16);
  70. p[2] = mymalloc(8);
  71. myfree(p[1]);
  72. p[1] = mymalloc(8);
  73. p[3] = mymalloc(8);
  74. myfree(p[3]);
  75. myfree(p[1]);
  76. myfree(p[2]);
  77. myfree(p[0]);
  78. return 0;
  79. }
  80.  
Success #stdin #stdout 0s 1788KB
stdin
Standard input is empty
stdout
==0x8581000
mymalloc(8) -> 0x8581004
* 0x8581000, 0x8581004 - 0x858100b: used 8
==0x858100c
mymalloc(16) -> 0x8581010
* 0x8581000, 0x8581004 - 0x858100b: used 8
* 0x858100c, 0x8581010 - 0x858101f: used 16
==0x8581020
mymalloc(8) -> 0x8581024
* 0x8581000, 0x8581004 - 0x858100b: used 8
* 0x858100c, 0x8581010 - 0x858101f: used 16
* 0x8581020, 0x8581024 - 0x858102b: used 8
==0x858102c
myfree(0x8581010)
* 0x8581000, 0x8581004 - 0x858100b: used 8
* 0x858100c, 0x8581010 - 0x858101f: free 16
* 0x8581020, 0x8581024 - 0x858102b: used 8
==0x858102c
mymalloc(8) -> 0x8581010
* 0x8581000, 0x8581004 - 0x858100b: used 8
* 0x858100c, 0x8581010 - 0x8581017: used 8
* 0x8581018, 0x858101c - 0x858101f: free 4
* 0x8581020, 0x8581024 - 0x858102b: used 8
==0x858102c
mymalloc(8) -> 0x8581030
* 0x8581000, 0x8581004 - 0x858100b: used 8
* 0x858100c, 0x8581010 - 0x8581017: used 8
* 0x8581018, 0x858101c - 0x858101f: free 4
* 0x8581020, 0x8581024 - 0x858102b: used 8
* 0x858102c, 0x8581030 - 0x8581037: used 8
==0x8581038
myfree(0x8581030)
* 0x8581000, 0x8581004 - 0x858100b: used 8
* 0x858100c, 0x8581010 - 0x8581017: used 8
* 0x8581018, 0x858101c - 0x858101f: free 4
* 0x8581020, 0x8581024 - 0x858102b: used 8
==0x858102c
myfree(0x8581010)
* 0x8581000, 0x8581004 - 0x858100b: used 8
* 0x858100c, 0x8581010 - 0x858101f: free 16
* 0x8581020, 0x8581024 - 0x858102b: used 8
==0x858102c
myfree(0x8581024)
* 0x8581000, 0x8581004 - 0x858100b: used 8
==0x858100c
myfree(0x8581004)
==0x8581000