我正在尝试通过系统调用分配内存并管理返回缓冲区来实现我自己的堆内存分配器。返回值:sbrk()
void *sbrk(intptr_t increment);
来自man sbrk
:
成功时,sbrk() 返回上一个程序中断。(如果增加了中断,那么这个值是一个指向新分配内存开始的指针)。出错时,返回 (void *) -1,并将 errno 设置为 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;
}
使用 gcc 和 gcc 标志编译:cc main.c -pedantic -Wconversion -Werror
程序按预期运行,但我不明白为什么 linux 分配大量内存,2200hex 字节,而我只要求 4096?
添加 gcc 标志之一-ansi
或-std=c89
产生以下编译错误:
在函数'extend_heap'中:main.c:15:20:错误:从'int'初始化'void *'使指针从整数而不进行强制转换[-Werror=int-conversion] 15 | 无效 *sp = sbrk(ALIGN(nbytes, VP_ALIGNMENT)); | ^~~~ main.c:在函数'main'中:main.c:31:22:错误:从'int'初始化'void *'使指针从整数而不进行强制转换[-Werror = int-conversion] 31 |
无效 *cbrk = sbrk(0); | ^~~~
sbrk
返回void*
。为什么我收到上面的错误?我的 glibc 版本 = 2.31,gcc 版本 9.3.0
谢谢。