使用mmap奇怪的段错误重新编码malloc

时间:2018-04-24 10:35:28

标签: c memory segmentation-fault malloc

我实际上正在使用mmap函数重新编码malloc,问题是我在分配的内存结束之前很大程度上得到了段错误。 我找不到代码中的问题。

在第一次调用malloc时调用init()函数,然后调用search_for_free_space()。

我正在使用mmap(100页)分配409600个字节,但是在没有理由的情况下仅使用26000个字节后,代码就会出现段错误。

当我将mmap的大小乘以10时,会出现段错误,但我确认给我的mmap的大小是409600而不是更少。

段错误应该只在使用了所有内存之后出现,因为我还没有完成代码的下一部分,但它看起来太早了。

代码(你可以运行它):

#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>

# define PAGE_SIZE getpagesize()

typedef struct  s_zone
{
    int             size;
    int             free;
    struct s_zone   *next;
}               t_zone;

typedef struct  s_e
{
    t_zone  *tiny;
}               t_e;

static t_e  g_e;

void    *allocate(size_t size)
{
    printf("%s", "allocated memory: ");
    printf("%d\n", (int)size);
    return (mmap(NULL, size, PROT_READ | PROT_WRITE,
        MAP_PRIVATE | MAP_ANON, -1, 0));
}

void    *init_tiny(size_t size)
{
    g_e.tiny = (t_zone*)allocate((PAGE_SIZE * 100));
    g_e.tiny->size = size;
    g_e.tiny->free = 0;
    g_e.tiny->next = g_e.tiny + sizeof(t_zone) + size;
    g_e.tiny->next->size = PAGE_SIZE;
    g_e.tiny->next->free = 1;
    g_e.tiny->next->next = NULL;
    return (g_e.tiny + sizeof(t_zone));
}

void    *search_for_free_space(size_t size, t_zone *zone)
{
    size_t  i;

    while (zone->free != 1 || zone->size < size)
        zone = zone->next;
    zone->free = 0;
    zone->size = size;
    zone->next = zone + sizeof(t_zone) + size;
    zone->next->size = PAGE_SIZE;
    zone->next->free = 1;
    zone->next->next = NULL;
    return (zone + sizeof(t_zone));
}

void    *malloc2(size_t size)
{
    if (g_e.tiny == NULL)
        return (init_tiny(size));
    else
        return (search_for_free_space(size, g_e.tiny));
    return (NULL);
}

int     main(void)
{
    int     i;

    i = 0;
    while (i < 300)
    {
        malloc2(2000);
        i++;
        printf("%s", "used memory: ");
        printf("%d\n", (int)((2000 * i) + (i * sizeof(t_zone))));
    }
    return (0);
}

1 个答案:

答案 0 :(得分:0)

正如Mevets所指出的,问题确实是

zone + sizeof(t_zone) + size;

sizeof(t_zone)类型为zone时,要将指针增加t_zone *个字节,只需添加 1 即可。即,zone + 1

然后你需要添加 size 字符,即

(t_zone *)((char *)(zone + 1) + size)

但是你还必须小心保持tzone结构的自然对齐;尤其是返回指向_Alignof (max_align_t)的指针。如果tzone已经以相同的对齐方式自然对齐,或者甚至与max_align_t大小相同,那么这将是最简单的;如果大小向上舍入到max_align_t的最接近倍数。