簡體   English   中英

如何分配頁面大小對齊的內存?

[英]How allocate memory which is page size aligned?

我需要分配應該頁面大小對齊的內存。 我需要將此內存傳遞給ASM代碼,該代碼計算所有數據塊的xor。 我需要用malloc()來做這個。

您應該使用這些功能。

如果不能,無論出於何種原因,那么通常這樣做的方法是將塊大小添加到分配大小,然后使用整數數學技巧來舍入指針。

像這樣的東西:

/* Note that alignment must be a power of two. */
void * allocate_aligned(size_t size, size_t alignment)
{
  const size_t mask = alignment - 1;
  const uintptr_t mem = (uintptr_t) malloc(size + alignment);
  return (void *) ((mem + mask) & ~mask);
}

這還沒有經過深刻的測試,但你明白了。

請注意,以后找出正確指向free()內存的指針是不可能的。 要解決這個問題,我們必須添加一些額外的機制:

typedef struct {
  void *aligned;
} AlignedMemory;

AlignedMemory * allocate_aligned2(size_t size, size_t alignment)
{
  const size_t mask = alignment - 1;
  AlignedMemory *am = malloc(sizeof *am + size + alignment);
  am->aligned = (void *) ((((uintptr_t) (am + 1)) + mask) & ~mask);
  return am;
}

這會稍微包裝指針技巧,並為您提供一個可以free()的指針,但是您需要取消引用aligned指針以獲得正確對齊的指針。

我認為只有malloc才有可能。 你可以使用memalign()

char *data = memalign(PAGESIZE, alloc_size);

其中PAGESIZE是頁面的大小, alloc_size是將分配的內存大小。

可以使用sysconf(_SC_PAGESIZE)找到頁面的大小。

使用posix_memalign獲取已對齊的內存。

注意: vallocmemalign都已過時。

使用valloc而不是malloc -它具有相同簽名malloc ,但它分配頁對齊的內存。 請注意,您仍然使用free()隨后free()內存。

另請注意, valloc在技​​術上已經過時,因此請考慮使用posix_memalign ,盡管這不是malloc的簡單替代品,因為它具有非常不同的函數簽名。

//面向Linux,//看看我的詭計來安排自己

我剛寫了一個程序,它必須分配硬件頁面對齊的內存; 這里是包含main()函數的程序

main()函數調用一個Func_a()函數,該函數調用一個Func_b()函數調用前面提到的Func_a()函數,依此類推......並且沒有停止條件,因此無限期地燒掉程序堆棧,最終導致SIGSEGV。

這應該對你有所幫助:

#include "Func_A.h"
#include "Func_B.h"


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

#define STACK_SIZE (1024 * 1024)

int main(void)
{
  // Allocate a 2nd stack for the SIG_SEGV signal handler
  long pgsz = sysconf(_SC_PAGESIZE);
  printf("Page size is %ld\n", pgsz);

  long stacksize = STACK_SIZE;

  long sigstkpages = (STACK_SIZE + (pgsz - 1) ) / pgsz;

  void* newstack = calloc(sigstkpages, pgsz);
  if (NULL == newstack)
  {
    perror("calloc()\n");
    exit(2);
  }
  newstack = (void*) (((((long) newstack) + (pgsz - 1)) / pgsz) * pgsz);
  void* newstackhigh = (void*) (((long) newstack) + (stacksize - 1));
  stacksize = (newstackhigh - newstack) + 1;
  printf("Stack size is %ld\n", stacksize);

  printf("New Stack spans %p-%p  (%ld pages)\n", newstack, newstackhigh, sigstkpages);

  a();
}

它的輸出是:

頁面大小是4096堆棧大小是1048576新堆棧跨度0x7f28435cd000-0x7f28436ccfff(256頁)Erreur de segmentation(core dumped)

預計coredump在這里。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM