I am trying to implement my own heap memory allocator, by allocating memory via sbrk()
system call, and managing the return buffer. void *sbrk(intptr_t increment);
return value:
From man sbrk
:
On success, sbrk() returns the previous program break. (If the break was increased, then this value is a pointer to the start of the newly allocated memory). On error, (void *) -1 is re‐ turned, and errno is set to ENOMEM
#include <gnu/libc-version.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
/*
puts (gnu_get_libc_version ());
*/
#define VP_ALIGNMENT (4096)
#define ALIGN(size,alignment) ( ((size) + (alignment-1)) & ~((alignment-1)) )
static void *extend_heap(int nbytes)
{
void *sp = sbrk(ALIGN(nbytes, VP_ALIGNMENT));
if (sp == (void*)-1) {
perror("fails to retrieve program brk");
}
return sp;
}
struct S{
char m[4096];
};
int main() {
/* get current brk */
void *cbrk = sbrk(0);
printf("current prog brk: %p\n",cbrk);
/*allocate 4096 bytes and get pointer to the start of the buffer*/
struct S *buf = (struct S*)extend_heap(4000);
printf("prog brk after allocation: %p\n",sbrk(0));
int c=4096;
do {
buf->m[4096-c] = 'a';
} while(--c);
c=4096;
do {
assert(buf->m[4096-c] == 'a');
} while(--c);
return 0;
}
Compile with gcc & gcc flags: cc main.c -pedantic -Wconversion -Werror
the program run as expected, but i dont understand why linux allocates a huge amount of memory, 2200hex bytes when i have asked only for 4096 ?
adding one of the gcc flags -ansi
or -std=c89
produce compilation errors below:
In function ‘extend_heap’: main.c:15:20: error: initialization of ‘void *’ from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion] 15 | void *sp = sbrk(ALIGN(nbytes, VP_ALIGNMENT)); | ^~~~ main.c: In function ‘main’: main.c:31:22: error: initialization of ‘void *’ from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion] 31 |
void *cbrk = sbrk(0); | ^~~~
sbrk
returns void*
.
why I am getting the error above?
My glibc version = 2.31, gcc version 9.3.0
Thanks.