Something hooked me to the general distrust of the implementation of its malloc through sbrk.
Here is a very simple (essentially stupid), but working program, just to demonstrate the possibility of working with sbrk() .
Since the whole group of functions (malloc / calloc / realloc / free) is used by the library software together, it is impossible to implement malloc alone.
#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> static void *start; void * get_memstart () { return start; } // size multiples 16, allocated to bound multiples 16 struct bhdr { struct hdr { size_t bsize; uint cnt; char is_free; } hdr; char pad[(16 - sizeof(struct hdr)) & 15]; }; // each malloc returns new sbrk block void * malloc (size_t size) { static uint cnt = 0; const char *mtxt = "mmalloc\n"; if (write(1, mtxt, strlen(mtxt))) cnt++; if (!size) return 0; // increase space to mutilpe 16 for good bounding struct bhdr *p = (typeof(p))sbrk((15 + size + sizeof(*p)) & ~15); if ((long)p == -1L) return 0; if (!start) start = p; p->hdr.bsize = size; p->hdr.cnt = cnt; p->hdr.is_free = 0; return p + 1; } void * calloc (size_t nmemb, size_t size) { const char *mtxt = "mcalloc\n"; void *p = 0; if (write(1, mtxt, strlen(mtxt))) { p = malloc(nmemb * size); if (p) memset(p, 0, nmemb * size); } return p; } // mark early allocated block as free if bound is multiple 16 void free (void *ptr) { const char *mtxt = "mfree\n"; if (write(1, mtxt, strlen(mtxt))) if (!ptr || (long)ptr & 15) return; struct bhdr *p = (typeof(p))ptr; p[-1].hdr.is_free = 1; } // if new size greater than old size returns copy in new block void * realloc (void *ptr, size_t size) { const char *mtxt = "mrealloc\n"; if (write(1, mtxt, strlen(mtxt))) if (!ptr) return malloc(size); if ((long)ptr & 15) return 0; if (!size) { free(ptr); return (void *)-1L; } struct bhdr *p = (typeof(p))ptr; size_t tsz = p[-1].hdr.bsize; if (tsz >= size) return ptr; void *nptr = malloc(size); if (nptr) memcpy(nptr, ptr, tsz); return nptr; } int main (int ac, char *av[]) { struct bhdr b; printf("Hello, sbrk/malloc!\nbhdr: %d pad: %d hdr: %d\n", (int)sizeof(b), (int)sizeof(b.pad), (int)sizeof(b.hdr)); char *s = 0; size_t n; errno = 0; while ((fputs("Enter: ", stdout), getline(&s, &n, stdin)) > 0) { printf("read %s", s); if (*s == '.') { puts("New line mem"); free(s); s = 0; } } perror("stdin"); return fcloseall(); }
All the "oddities" of the write() code are associated with annoying (idiotic) warnings gcc / g ++ (g ++. Real (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4) 5.4.0) caused with optimization keys ( -O... ) when the write result is not used.
brk()/sbrk()) pair: "It’s even more practical to never use these procedures. A program that uses them cannot then also use malloc (), and it creates a big problem, since many elements of the standard library rely on the use of malloc (). Therefore, using brk () or sbrk () can lead to hard-to-find program crashes. " - PinkTux