重新编码malloc-无法返回内存

时间:2018-11-30 12:35:22

标签: c unix return malloc mmap

我必须在C中重新编码函数malloc(3)。
我必须使用mmap()syscall才能分配页面。

我已经制作了一些版本,但是由于无法正常工作,我决定在一个函数中制作一个小型且快速的版本,以便进行调试。

这是我使用malloc编译测试程序的方式:
gcc unit_test.c libft/libft.a -L. -lft_malloc
这是我的makefile编译我的malloc.so的方式:
gcc -g -shared -undefined dynamic_lookup -o libft_malloc.so srcs/malloc.c srcs/debug.c

我的unit_test.c程序非常简单,我想分配一个大小为10的字符串,将其所有字符设置为'a',然后打印:

#include "libft/libft.h"
#include "incs/malloc.h"

int         main(void)
{
    ft_putstr_fd("TEST 01\n", 2);
    char    *str;
    int     i;

    str = NULL;
    str = (char *)malloc(sizeof(char) * 10);
    if (!str)
    {
        ft_putstr_fd("MALLOC FAILED\n", 2);
        return (-1);
    }

    ft_putstr_fd("MALLOC SUCCESS\n", 2);
    i = 0;
    while (i < 9)
    {
        str[i] = 'a';
        i++;
    }
    str[i] = '\0';
    ft_putchar_fd('\n', 2);
    ft_putstr_fd(str, 2);
    ft_putchar_fd('\n', 2);
    return (0);
}

不过没问题。它应该可以工作(与真正的malloc一样)。

这是我的“阻止”结构:

typedef struct          s_block
{
    size_t              size;
    char                *memory;
    struct s_block      *next;
    struct s_block      *prev;
}                       t_block;

size是要查询的内存的大小,memory是指向要返回的内存的第一个地址的指针(我将其强制转换为char *),next和prev是一个链接列表。

最后,这是我的malloc函数:

void        *malloc(size_t size)
{
    char        *memory;
    t_block     *block;
    int         i;
    size_t      total_size;

    memory = NULL;
    i = 0;

    total_size = size + sizeof(t_block);

    while (total_size % 16)    // Align memory
        total_size++;

    memory = mmap(0, total_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
    while (i < total_size)
    {
        memory[i] = 'z';
        i++;
    }
        db_putstr_fd("Printing memory...\n", 2);
        db_putstr_fd(memory, 2);
        db_putchar_fd('\n', 2);
    block = (t_block *)&memory;
    block->size = size;
    block->next = NULL;
    block->prev = NULL;
        db_putstr_fd("Block size = ", 2);
        db_putnbr_fd(block->size, 2);
        db_putchar_fd('\n', 2);
    block->memory = (char *)&block + sizeof(t_block);
    i = 0;
    while (i < block->size)
    {
            db_putstr_fd("i = ", 2);
            db_putnbr_fd(i, 2);
            db_putstr_fd("\tsize = ", 2);
            db_putnbr_fd(block->size, 2);
            db_putchar_fd('\n', 2);
        block->memory[i] = 'a';
        i++;
    }

        db_putstr_fd("Out of loop\n", 2);
        db_putstr_fd(block->memory, 2);
        db_putchar_fd('\n', 2);

    return (block->memory);
}

因此,我映射了一个char *内存(当我确定它可以正常工作时,将被页面替换)。我将块设置为该内存的开头,然后初始化所有块结构变量。
我的问题可能是当我设置块的字符串地址时。
我自愿缩进了调试行,因为它们很多,因此您可以更好地看到有趣的行;但我决定让他们向您展示结果:

TEST 01
Printing memory...
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Block size = 10
i = 0   size = 10
i = 1   size = 10
i = 2   size = 10
i = 3   size = 10
i = 4   size = 10
i = 5   size = 10
i = 6   size = 10
i = 7   size = 10
i = 8   size = 10
i = 9   size = 10
Out of loop
aaaaaaaaaa
[1]    59894 segmentation fault  ./a.out

如您所见,我可以在malloc的内存中写入内容,但是当我返回它时,则是程序segfault。我认为它发生在unit_test.c文件的第11行,但是为什么呢?

如何在malloc函数中写入内存字符串,但无法将其返回给调用malloc的程序?
我想念什么吗?

0 个答案:

没有答案