在Linux中对sbrk(0)的初始调用是否总是返回一个与8个字节对齐的
我正在研究这里定义的malloc的实现:
http://www.inf.udec.cl/~leo/Malloc_tutorial.pdf. 作者创建了一个自然地在4字节边界上对齐的元数据结构,然后在元数据结构之后将x字节的请求与4字节边界对齐,该元数据结构实际上充当块的头部. pdf指出,由于元数据和请求现在已对齐,因此结果数据将完全对齐. 解决方法
standard for
brk and sbrk 明确没有指定返回的地址是否以任何方式对齐.在Mac OS X(可能还有其他BSD系统)上,大小/地址是页面对齐的,但在Linux上没有这样的舍入,因为可以使用这个小程序轻松测试:
#include <unistd.h> #include <stdio.h> int main() { void *p; p = sbrk(0); printf("Initial brk: %pn",p); p = sbrk(1); // Increase the brk (returns OLD brk!) p = sbrk(0); // Get the new brk printf("New brk: %pn",p); return 0; } 在我的一个系统上,输出是: Initial brk: 0x602000 New brk: 0x602001 但你问了最初的电话. Linux手册页指出:
单位化数据段也称为BSS.这里的关键字是段,因此初始值很可能始终是页面对齐的. 如果您想要安全并检查,您可以通过获取页??面大小的模数来验证初始地址(您可以通过 更新:所以我好奇并且挖了一点.在man-page中,我已经读过brk和sbrk是在内核的sys_brk上实现的.它在内核源代码中的实现可以在mm / mmap.c中找到(对于没有内存管理单元的系统,可以找到mm / nommu.c;我们将忽略这一点).在mm / mmap.c中的brk实现中,我们找到了这一行: newbrk = PAGE_ALIGN(brk); (“brk”这里是参数,而不是函数.)所以内核确实进行页面对齐…排序:虽然计算是使用页面对齐的值完成的,并且任何必要的内存分配是页面对齐的,但是存储的值是brk实际上是你传递的指针值: mm->brk = brk; 因此,在用户空间中,即使内核确实发生了任何页面操作,它看起来也不像.我看了3.17.5和2.4.37版本,行为是一样的. 关于初始值,在fs / binfmt_elf.c(实现ELF链接)中,我们找到一个函数set_brk,它设置初始“brk”值(mm-> start_brk).该值明确是页面对齐的.对于处理旧的a.out格式的fs / binfmt_aout.c和处理HP-UX SOM格式的fs / binfmt_som.c(之前从未听说过),情况也是如此.还有fs / binfmt_flat.c,它设置初始brk值但没有明确对齐;这里的值是隐式对齐的.所以看起来初始值始终是页面对齐的.至少它保证与ELF文件页面对齐,这是我们关心的“普通”系统. glibc简单地包装sys_brk并添加簿记以正确实现sbrk.因此glibc的brk行为是内核的行为,返回值sys_brk存储在内部隐藏变量__curbrk中,以便sbrk可以正确计算新地址. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |