【问题标题】:How does one align a pointer that is allocated on the heap (using malloc)?如何对齐在堆上分配的指针(使用 malloc)?
【发布时间】:2021-12-26 20:18:23
【问题描述】:

当我尝试将 calloc 返回的指针与 BY2PAGE 对齐时,这会导致段错误。有没有办法(甚至合法)修改指针,使其在分配后对齐?

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define BY2PG 0x1000
char * vm;


static int roundup(u_int n, int align) {
    if(n % align == 0) ; 
    // is already aligned so
    // no action required, else
    // align it:
    else n += (align - (n % align));
    
    return n;
}

int main() {

    vm = (char *) calloc(0x100000, sizeof(char));

    vm = (char *) roundup((u_int)vm, BY2PG);

    vm[0] = 5; // seg fault
}

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    不要用脆弱的用户代码冒险实施和未定义的行为,为了对齐分配,使用:

    #include <stdlib.h> // Since C11
    void *aligned_alloc(size_t alignment, size_t size);
    

    aligned_alloc函数为对齐指定对齐的对象分配空间,其大小由大小指定,...


    OP 假设 1)(u_int)vm 不会丢失重要信息(我认为这是 seg 故障源)2)调整后的整数,转换为 int,转换回指针是有效的 3)@ 987654326@返回非NULL@Lindydancer

    即使最初的分配也被怀疑为calloc(0x100000, sizeof(char));,在有问题的roundup() 之后有多少0x1000 大小的块可供使用。

    【讨论】:

      【解决方案2】:

      感谢@WeatherVane - 这个版本按我的预期工作

      #include <unistd.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <stdbool.h>
      
      #define BY2PG 0x1000
      char * vm;
      
      
      static uintptr_t roundup(uintptr_t n, int align) {
          if(n % align == 0) ; 
          // is already aligned so
          // no action required, else
          // align it:
          else n += (align - (n % align));
          
          return n;
      }
      
      int main() {
      
          vm = (char *) calloc(0x100000, sizeof(char));
      
          printf("%08x\n", vm);
      
          vm = (char *) roundup((uintptr_t)vm, BY2PG);
      
          printf("%08x\n", vm);
      
          vm[0] = 5;
      
          printf("%d\n", vm[0]);
      }
      

      【讨论】:

      • 这依赖于未定义的行为(因为您打算将它用于char* 以外的事物,因为您使用 if ``intptr_t` 而不是 char*)。你最终也会得到比需要更少的内存。 (您需要过度分配BY2PG-1 以避免此问题。)对于这两个原因,另一个答案更好。
      猜你喜欢
      • 2023-03-10
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多