C:mmap在0xFFFFFF处初始化
我目前正在为一个C项目做一个内存分配器,我面临着一些我不理解的事情 我正在调用mmap为我的程序保留堆,在那里我将放置一些头文件 我有C:mmap在0xFFFFFF处初始化,c,memory-management,segmentation-fault,mmap,C,Memory Management,Segmentation Fault,Mmap,我目前正在为一个C项目做一个内存分配器,我面临着一些我不理解的事情 我正在调用mmap为我的程序保留堆,在那里我将放置一些头文件 我有 void * START_ADDRESS; int MEMORY_INITIALIZED; void* Mem_Init(int sizeOfRegion){ START_ADDRESS = mmap(NULL, sizeOfRegion, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_FILE |MAP_PR
void * START_ADDRESS;
int MEMORY_INITIALIZED;
void* Mem_Init(int sizeOfRegion){
START_ADDRESS = mmap(NULL, sizeOfRegion, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_FILE |MAP_PRIVATE, -1,0);
header_t* startingHeader = START_ADDRESS;
//rest of the fontion
}
void* Mem_Alloc(int size){
if(MEMORY_INITIALIZED==0){
START_ADDRESS= Mem_Init(size);
//rest of the funtion
}
当我在此代码上使用errno时,它会返回无效参数错误
为什么当我使用Mem_Init方法调用mmap时,它会返回一个有效的地址?为什么当我在Mem_Alloc方法中调用Mem_Init时,它会返回我invalidArgument
提前感谢对代码进行了一些小的更改,您的代码似乎可以正常工作:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
void * START_ADDRESS;
int MEMORY_INITIALIZED = 0;
void* Mem_Init(int sizeOfRegion){
START_ADDRESS = mmap(NULL, sizeOfRegion, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_FILE |MAP_PRIVATE, -1,0);
if ((void *) -1 == START_ADDRESS) {
printf("Could not map memory: %s\n", strerror(errno));
}
printf("%p\n", START_ADDRESS);
void* startingHeader = START_ADDRESS;
//rest of the fontion
return startingHeader;
}
void* Mem_Alloc(int size){
if(MEMORY_INITIALIZED==0){
START_ADDRESS= Mem_Init(size);
}
//rest of the funtion
return START_ADDRESS;
}
int main(void) {
Mem_Alloc(1024);
return 0;
}
我认为最重要的变化是MEMORY_INITIALIZED设置为0,但语言律师向我保证,遵循C89标准的编译器已经做到了这一点。我终于找到了错误 在老师给我们的测试程序中,他试图分配一个0大小的头,当你试图分配一个空指针时,mmap失败了 一个简单的修正是
void* Mem_Init(int sizeOfRegion){
if(sizeOfRegion==0) sizeOfRegion = 1024; //1024 is an exemple
START_ADDRESS = mmap(NULL, sizeOfRegion, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_FILE |MAP_PRIVATE, -1,0);
if ((void *) -1 == START_ADDRESS) {
printf("Could not map memory: %s\n", strerror(errno));
}
感谢支持人员您的代码无效C。请创建一个。
0xffffffff
可能是MAP\u失败
,这意味着它出错errno
将包含原因。同时使用MAP\u匿名
和MAP\u文件
是没有意义的。Camel大小写已经够糟糕了,但是所有的caps变量名?啊!有点体面,伙计!你的问题很不清楚。请按要求发布MCVE。例如,“当我调用Mem_Init时,它会返回一个类似0xbcfd210的地址,这是正常的,但当我在Mem_Alloc方法中调用它时,mmap会返回0xffffff”。这真的没有道理。显示的调用mmap
的唯一位置是Mem_Init
。那么,有些呼叫失败而有些呼叫不成功到底是什么意思呢?在代码中显示这些精确调用。全局变量已自动初始化为0。这不可能是问题所在。也许是因为OP使用的是虚拟机?(参见前面的评论)此外,我认为OP不想多次使用mmap,因此只应该在主界面中调用Mem_Alloc。这就是问题所在,从Mem_Alloc调用mmap或者直接从Mem_InitI调用mmap意味着在main中调用Mem_Alloc。更改后,代码仍然有效。代码是在虚拟机上编译和运行的。我认为这是不对的。从手册页:如果addr为NULL,那么内核选择创建映射的地址;这是创建新映射的最方便的方法。
是的,我已经检查过了,我同意你的观点。但当我们要求一个大小为空的区域时,我认为内核会在一个有效的位置初始化一个大小为0的映射,为了尽可能减少冲突,它会在内存的末尾初始化它。这是我的观点,但可能效果不同。。。。
void* Mem_Init(int sizeOfRegion){
if(sizeOfRegion==0) sizeOfRegion = 1024; //1024 is an exemple
START_ADDRESS = mmap(NULL, sizeOfRegion, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_FILE |MAP_PRIVATE, -1,0);
if ((void *) -1 == START_ADDRESS) {
printf("Could not map memory: %s\n", strerror(errno));
}