C:mmap在0xFFFFFF处初始化

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

我目前正在为一个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_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));
    }