首页 > 解决方案 > 使用此内存分配器时收到分段错误

问题描述

我正在尝试实现一个可以由多个进程一次调用的内存分配器,所以我使用共享内存来保持分配的第一个和最后一个内存块的信息,两者都放在共享内存的前 32 个字节和之后我试图从共享内存中的 getpagesize() 偏移量进行简单分配,以查看它是否有效,但是在使用它分配一个简单的整数变量时,我不断收到分段错误,我不知道为什么。

#include <unistd.h>
#include <string.h>
#include <pthread.h>
/* Only for the debug printf */
#include <stdio.h>

#include <sys/mman.h>
#include <sys/stat.h>       
#include <fcntl.h>          
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

typedef char ALIGN[16];

union header {
    struct {
        size_t size;
        unsigned is_free;
        union header *next;
    } s;
    /* force the header to be aligned to 16 bytes */
    ALIGN stub;
};
typedef union header header_t;


header_t *get_free_block(size_t size)
{
    char shm_name[] = "memalloc";
    int shm_fd;
    shm_fd = shm_open(shm_name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
    if (shm_fd < 0)
    {
        perror(NULL);
        return NULL;
    }


    size_t shm_size = 10 * getpagesize();
    if (ftruncate(shm_fd, shm_size) == -1)
    {
        perror(NULL);
        shm_unlink(shm_name);
        return NULL;
    }

    char* shm_ptr = mmap(0, shm_size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
        if (shm_ptr == MAP_FAILED)
        {
            perror(NULL);
            shm_unlink(shm_name);
            return NULL;
        }

    header_t *head;
    if (shm_ptr)
        head = (header_t*)shm_ptr;
    else
        head = NULL;
    header_t *tail;
    if (head)
        tail = (header_t*)(shm_ptr + 16);
    else
        tail = NULL;
    header_t *curr = head;
    while(curr) {
        /* see if there's a free block that can accomodate requested size */
        if (curr->s.is_free && curr->s.size >= size)
            return curr;
        curr = curr->s.next;
    }
    return NULL;
}


void *malloc(size_t size)
{

    char shm_name[] = "memalloc";
    int shm_fd;
    shm_fd = shm_open(shm_name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
    if (shm_fd < 0)
    {
        perror(NULL);
        return NULL;
    }


    size_t shm_size = 10 * getpagesize();
    if (ftruncate(shm_fd, shm_size) == -1)
    {
        perror(NULL);
        shm_unlink(shm_name);
        return NULL;
    }

    char* shm_ptr = mmap(0, 32, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
        if (shm_ptr == MAP_FAILED)
        {
            perror(NULL);
            shm_unlink(shm_name);
            return NULL;
        }
    header_t *head;
    if (shm_ptr)
        head = (header_t*)shm_ptr;
    else
        head = NULL;
    header_t *tail;
    if (head)
        tail = (header_t*)(shm_ptr + 16);
    else
        tail = NULL;

    size_t total_size;
    void *block;
    header_t *header;
    if (!size)
        return NULL;

    header = get_free_block(size);
    if (header) {
        /* Woah, found a free block to accomodate requested memory. */
        header->s.is_free = 0;

        return (void*)(header + 1);
    }
    /* We need to get memory to fit in the requested block and header from OS. */
    total_size = sizeof(header_t) + size;
    int nr_pagesize = 1;

    block = mmap(0, total_size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, nr_pagesize * getpagesize());
    if (block == MAP_FAILED)    
    {
        perror(NULL);
        shm_unlink(shm_name);

        return NULL;

    }
    header = block;
    header->s.size = size;
    header->s.is_free = 0;
    header->s.next = NULL;
    if (!head)
        head = header;
    if (tail)
        tail->s.next = header;
    tail = header;


    return (void*)(header + 1);
}

这是测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
    int *x = (int*)malloc(sizeof(int));
    return 0;
}

我在终端上使用的命令是:

gcc -o memalloc.so -fPIC -shared memalloc.c
export LD_PRELOAD=$PWD/memalloc.so
gcc helloworld.c -o hello

编译测试程序后,我得到了分段错误。

标签: cshared-memory

解决方案


推荐阅读