我第一次调用malloc()时遇到了一个分段错误,这是在我使用mprotect()保护一个内存区域之后调用的。这是一个执行内存分配和保护的代码片段:
#define PAGESIZE 4096
void* paalloc(int size){ // Allocates and aligns memory
int type_size = sizeof(double);
void* p;
p = malloc(type_size*size+PAGESIZE-1);
p = (void*)(((long) p + PAGESIZE-1) & ~(PAGESIZE-1));
return p;
}
void aprotect(int size, void* array){ // Protects memory after values are set
int type_size = sizeof(double);
if (mprotect(array, type_size*size, PROT_READ)) {
perror("Couldn't mprotect");
}
}我想使用mprotect来避免任何写入数组的操作(它们是预先计算好的正弦/余弦值)。这是个愚蠢的想法吗?
发布于 2009-11-06 21:14:21
正如您可能已经知道的,mprotect只能以页为单位工作。在这种情况下,您正确地将块的开头与页面边界对齐,但是您没有确保您的分配延伸到您将在其中使用的最后一个页面的末尾。
这意味着您的mprotect保护的数据超过了分配的末尾(就在该页的末尾),这是下一个malloc调用假定它可以写入的空间。
最简单的解决方法是将malloc调用中的PAGE_SIZE - 1更改为PAGE_SIZE * 2。
发布于 2010-08-24 13:50:30
我建议你直接使用mmap来创建一个匿名映射,然后在你写完数组之后再对其调用mprotect。因为您总是分配整个页面,所以使用堆根本没有意义。它的主要用途是处理小(Ish)对象的分配和释放。在处理页面块时,它只会增加不必要的开销。
发布于 2009-11-06 21:13:53
caf已经确定了问题的原因。
我认为你可以不使用mprotect():如果它对你来说那么重要,在你的lookup.c中声明指针为静态的(或者不管它叫什么),然后有一个非静态的double get_sine(int index);函数。这样,lookup.c外部的代码只能调用get_sine(),而不能直接访问表。
另外,从我的mprotect()手册页:
mmap指出,m
()只能在从mmap(2)获得的内存区域上使用
(显然,这不适用于Linux。您使用的是哪种操作系统?)
https://stackoverflow.com/questions/1687415
复制相似问题