我需要分配内存,该内存应按页面大小对齐。 我需要将此内存传递给一个计算所有数据块异或的ASM
代码。 我需要使用malloc()
来完成此操作。
我需要分配内存,该内存应按页面大小对齐。 我需要将此内存传递给一个计算所有数据块异或的ASM
代码。 我需要使用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);
}
这个还没有进行深入的测试,但是你会明白意思。
请注意,后续将无法确定指向要释放内存的正确指针。为了解决这个问题,我们需要添加一些额外的机制:
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
相同的事情。在返回给用户的地址之前的4个字节中写入原始地址。 - Damonvoid *
不会自动转换为 uintptr_t
。 :) - unwind我认为仅使用malloc是不可能的。你可以使用memalign():
char *data = memalign(PAGESIZE, alloc_size);
其中PAGESIZE
是页面的大小,alloc_size
是将要分配的内存大小。
页面的大小可以使用sysconf(_SC_PAGESIZE)
来获取。
malloc
- 它与 malloc
具有相同的函数签名,但它分配的内存是页面对齐的。请注意,您仍然需要使用 free()
释放内存。valloc
在技术上已经过时了,因此考虑使用 posix_memalign,尽管这不像 malloc
那样简单,因为它具有非常不同的函数签名。valloc
已被记录为过时,请勿使用! - Basile Starynkevitchvalloc
还将存在很长一段时间。请注意,它不仅适用于 Linux,还适用于 BSD/Mac OS X/等等。但是,为了完整起见,我已添加了一个关于使用更加繁琐的 posix_memalign
的注释。 - Paul R// 面向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页) 分段错误(核心已转储)
在这里预期发生核心转储。
malloc()
完成这个任务。你为什么已经决定了解决方案呢? - David Heffernan