【问题标题】:Confused with pointer arithmetic对指针算法感到困惑
【发布时间】:2020-02-01 20:58:10
【问题描述】:

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

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

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

Pagesize 和 pagemask 前面定义如下

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);
    }
}

【问题讨论】:

  • &amp; 是二进制和。
  • 调用malloc 并立即对结果进行算术运算似乎是个坏主意。稍后您需要将原始指针传递给free
  • 选择一个随机数,你认为malloc 可能会返回。然后写在纸上。然后使用笔和纸执行第二个操作。对几个不同的数字执行此操作,您可能会开始看到一种模式。笔和纸仍然是程序员工具箱中两个非常重要的部分。

标签: c++ pointer-arithmetic


【解决方案1】:

初步说明

  • 内存“页”总是(嗯,实际上总是)的大小是 2 的幂。这意味着,对于给定的页大小,地址的高位表示一个页,而低位 - 一个偏移到页面中。
  • 不要写这种代码。进行显式转换;使用多个更简单的指令;尝试使用更有意义的变量名(例如offset_into_page = ((const uintptr_t) address) &amp; page_mask;)等等。

第一行

first 行执行以下操作:

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

我不清楚这为什么有用。

第二行

second 行执行以下操作:

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

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

【讨论】:

  • 酷。我明白你解释的大部分内容。我仍然困惑的是以下内容。在第一次分配之后,由于您丢弃了页面位并且只保留了偏移位,您不会弄乱您的指针吗?因此,在第二行中,您将指向一些不是由 malloc 分配的空间?
  • @AbdulRahman:等等,这两个任务应该一个接一个地发生?我以为他们是无关的......
  • 将使用我在书中看到的函数代码更新问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-11
  • 2013-12-25
相关资源
最近更新 更多