我必须在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的程序?
我想念什么吗?