我正在尝试了解内存映射的基础知识。 我写了下面的小程序:它分配一些字节作为参数传递,然后不断设置字节直到程序终止:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
printf("pid = %d\n", getpid());
double mb = strtod(argv[1], NULL);
size_t bytes = 1000 * mb;
printf("allocating %f mb, or %ld bytes\n", mb, bytes);
char* ptr = (char*)malloc(bytes);
printf("allocated at %p\n", ptr);
size_t i=0;
while (1) {
for (i=0; i<bytes; i++) {
ptr[i] = 'a';
}
}
return 0;
}
当我运行
./a.out 10000
然后为相应的pmap <pid> -X
运行pid
时,我发现ptr从0x7ff9cf753010
开始,但堆显示如下:
Address Perm Offset Device Inode Size Rss Pss Referenced Anonymous LazyFree ShmemPmdMapped FilePmdMapped Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked THPeligible Mapping
559eba856000 rw-p 00000000 00:00 0 132 4 4 4 4 0 0 0 0 0 0 0 0 0 [heap]
7ff9cf753000 rw-p 00000000 00:00 0 9768 9768 9768 9768 9768 0 0 0 0 0 0 0 0 0
我很困惑,因为大小是 9768,而不是 10,000。我猜 132 位是堆的某种标头?此外,指针值不一样......希望对此有所了解。
您看到的大小差异实际上并不是大小差异,这是由于
k
被用来表示 1000
和 1024
与 B
结合用于字节,有时使用 Ki
代替而是专门表示1024
,但情况并非总是如此,尤其是在较旧的界面中。
如果记住这一点并再次查看大小,您会发现
9768
正是您在 KiB 中分配的大小,四舍五入到最接近的页面大小倍数(通常为 4KiB):10,000,000 / 1024 = 9765.625
四舍五入到 9768
.
指针
7ff9cf753000
与 7ff9cf753010
的区别在于簿记标题 malloc
使用,您将丢失的字节归咎于此。