【问题标题】:recoding malloc with mmap strange segfault用 mmap 奇怪的段错误重新编码 malloc
【发布时间】:2018-10-04 14:06:20
【问题描述】:

我实际上是在使用 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);
}

【问题讨论】:

  • 请为崩溃提供minimal reproducible example
  • 感谢您对我添加的评论
  • 你的调试器应该能够告诉你段错误发生在哪里
  • zone + sizeof(t_zone) + size 将 sizeof() + size 值缩放 *zone 的大小;我想你想要“(t_zone * )((char * )(zone+1)+size)”。
  • 你的算法坏了。分配任何大于 PAGE_SIZE 的东西是不可能的。您需要跟踪可用内存,如果没有可用节点,只需将新块添加到列表末尾即可。抛弃“foo->next->size = PAGE_SIZE”逻辑。

标签: c memory segmentation-fault malloc


【解决方案1】:

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

zone + sizeof(t_zone) + size;

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

那你需要给这个加上size个字符,即

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多