我实际上正在使用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);
}
答案 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
的最接近倍数。