与指针算术混淆

Confused with pointer arithmetic

本文关键字:指针      更新时间:2023-10-16

谁能帮我理解这两行在做什么

buf = (char *)(malloc(2 * pagesize) & pagemask);
buf = (char *)(((long)buf + pagesize) & ∼pagemask);

我了解 malloc,但不确定&操作在两个表达式中试图实现什么

页面大小和页面掩码定义如下

pagesize = sysconf(_SC_PAGESIZE);
pagemask = pagesize - 1;

谢谢!

编辑1

这段代码来自Steve D. Pate的"Unix FileSystems"一书。

编辑2

这是完整的代码

#include <sys/unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include “sys/fs/vx_ioctl.h”
#define MB (1024 * 1024)
main(int argc, char argv[])
{
char        *buf;
int         i, fd, advisory;
long        pagesize, pagemask;
if (argc != 2) {
exit(1);
}
if (strcmp(argv[1], “VX_SEQ”) == 0) {
advisory = VX_SEQ;
} else if (strcmp(argv[1], “VX_RANDOM”) == 0) {
advisory = VX_RANDOM;
} else if (strcmp(argv[1], “VX_DIRECT”) == 0) {
advisory = VX_DIRECT;
}
pagesize = sysconf(_SC_PAGESIZE);
pagemask = pagesize - 1;
buf = (char *)(malloc(2 * pagesize) & pagemask);
buf = (char *)(((long)buf + pagesize) & ∼pagemask);
fd = open(“myfile”, O_RDWR);
ioctl(fd, VX_SETCACHE, advisory);
for (i=0 ; i<MB ; i++) {
read(fd, buf, 4096);
}
}

初步说明

  • 内存"页面"总是(好吧,实际上总是(的大小是 2 的幂。这意味着,对于给定的页面大小,地址的上位表示页面,而下位表示页面的偏移量。
  • 不要写这种代码。进行明确的转换;使用多个更简单的说明;尝试使用更有意义的变量名称(例如offset_into_page = ((const uintptr_t) address) & page_mask;(等等。

第一行

第一行执行以下操作:

  1. 分配 2 页的内存。
  2. 地址视为数字,仅将偏移量的位保留在分配区域开始的页面内。

我不清楚为什么这很有用。

第二行

第二行执行以下操作:

  1. buf的地址视为数字(尽管以歪曲、容易出错且不可移植的方式(。
  2. buf的地址向前移动一页。
  3. 保留地址的页位 - 获取 bif 中第一个页边界对齐的地址。

这牺牲了一些分配给buf的空间,使其对齐(并将其保持在实际分配的空间中。