【问题标题】:Pointer Arithmetic for mmapmmap 的指针算法
【发布时间】:2012-07-08 13:27:58
【问题描述】:

最近我试图修改某人的 mmap 代码并遇到以下错误。 (实际上我现在对他们的代码有点怀疑,因为看起来他们在做一些不必要的事情 - 尝试将 MAP_FIXED 与他们自己的页面对齐内存一起使用。手册页建议使用 NULL 调用 mmap 作为 addr 参数应该在 Linux 上执行此操作。) 所以我想我至少会测试使用 NULL 地址调用 mmap。但是,当我更改它时,我不太明白 gcc 向我抛出的错误。他们的代码工作正常,而我得到 左值需要作为赋值的左操作数

基本上他们在做以下事情:

    uint8_t * ptr = (uint8_t *)mem;
    if ((uint32_t)ptr % PAGE_SIZE)
    {
        ptr += PAGE_SIZE - ((uint32_t)ptr % PAGE_SIZE);
    }

其中 mem 是一些 malloc 内存的 void *。

我正在尝试或多或少地使用类型转换:

    if ((uint32_t)mem % PAGE_SIZE)
    {   
        (uint8_t *)mem += PAGE_SIZE - ((uint32_t)mem % PAGE_SIZE); /* ERROR */
    }

所以我认为我很聪明并删除了一个我认为不需要的变量。 有人可以告诉我为什么我的类型转换关闭了吗? 干杯。

【问题讨论】:

  • 这不是一个答案,但需要注意的是原始代码做错了很多事情。如果地址一开始是页面对齐的,他们的页面对齐代码将浪费一整页。 mmap(和MAP_FIXED)在malloc 获得的内存上可能是一个错误,除非你确定你永远不会释放它。

标签: c pointers casting mmap


【解决方案1】:

你犯的错误是:

(uint8_t *)mem += /* Anything.  */

您根本无法分配给强制转换的结果。强制转换的结果与原始表达式的值不同

想想这样做会有多奇怪:

(int) some_char_variable = 9999;

我有一次trouble for the same reason

使用临时变量,并写回结果,或者,正如 R.. 在他们的评论中所说:

mem = (void *) ( ( (uint8_t *) mem) + SOME_EXPRESSION );

【讨论】:

  • 感谢您认为我需要一双新的眼睛 :) 如果 += 将操作分开 :)
  • 不,这可以在没有温度的情况下工作:mem = (void *)((uint8_t *)mem + PAGE_SIZE - ((uint32_t)mem % PAGE_SIZE));
  • 它是一个,与临时对象有很大不同。
  • 顺便说一句,您的“我选择的解决方案”解决方案是错误的。这是一个别名违规并调用未定义的行为。如果你这样做,现实世界的编译器可以并且将会生成非工作代码。
  • 是的,我会说这个答案是错误的。正确答案只是 #define MY_DATA(bb) ( ((struct a_long_struct_name *) (bb)->aux) ) 而不是尝试使用 MY_DATA(bb) 作为左值(因为它不是,也不能是)。而是写bb->aux = malloc(...);
猜你喜欢
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多