【发布时间】: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