我正在尝试编写一个自定义 malloc,我已经从这个 github 存储库中获取了参考
https://github.com/FallAngel1337/mymalloc
我正在尝试使用 sbrk 创建一个已分配节点的单链表,如下所示,
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <assert.h>
struct metadata
{
size_t size;
unsigned char magic;
struct metadata *next;
};
struct metadata *head = NULL;
void *mymalloc(size_t size);
void myfree(void *ptr);
void *mymalloc(size_t size)
{
if (size == 0)
return NULL;
struct metadata *block = NULL;
block = sbrk(0);
size_t fsize = sizeof(block) + size;
sbrk(fsize);
block->next = NULL;
block->size = size - sizeof(struct metadata);
block->magic = 1;
if(NULL == head)
{
head = block;
printf("%d: %p\n", __LINE__, block->next);
}
else
{
struct metadata *tmp;
printf("%d: %p %p\n", __LINE__, tmp->next, head->next);
tmp = head;
while(NULL != tmp->next)
{
printf("%d: %p\n", __LINE__, tmp->next);
//if(head)
tmp = tmp->next;
}
tmp->next = block;
}
return (block+1);
}
int main(void)
{
int *arr, *prr;
arr = mymalloc(4);
prr = mymalloc(6);
if(NULL != arr)
{
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
printf("arr: %d %d %d\n", arr[0], arr[1], arr[2]);
}
if(NULL != prr)
{
prr[0] = 4;
prr[1] = 5;
prr[2] = 6;
printf("prr: %d %d %d\n", prr[0], prr[1], prr[2]);
}
//myfree(arr);
return 0;
}
(忽略它还没有实现 myfree。)上面的代码适用于下面的命令,
gcc -g3 -o malloctest malloctest.c
❯ ./malloctest1
36: (nil)
41: 0xc35f415e415d415c (nil)
arr: 1 2 3
prr: 4 5 6
但是当我如下删除一些打印件时
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <assert.h>
struct metadata
{
size_t size;
unsigned char magic;
struct metadata *next;
};
struct metadata *head = NULL;
void *mymalloc(size_t size);
void myfree(void *ptr);
void *mymalloc(size_t size)
{
if (size == 0)
return NULL;
struct metadata *block = NULL;
block = sbrk(0);
size_t fsize = sizeof(block) + size;
sbrk(fsize);
block->next = NULL;
block->size = size - sizeof(struct metadata);
block->magic = 1;
if(NULL == head)
{
head = block;
}
else
{
struct metadata *tmp;
tmp = head;
while(NULL != tmp->next)
{
printf("%p %p\n", tmp->next, NULL);
//if(head)
tmp = tmp->next;
}
tmp->next = block;
}
return (block+1);
}
int main(void)
{
int *arr, *prr;
arr = mymalloc(4);
prr = mymalloc(6);
if(NULL != arr)
{
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
printf("arr: %d %d %d\n", arr[0], arr[1], arr[2]);
}
if(NULL != prr)
{
prr[0] = 4;
prr[1] = 5;
prr[2] = 6;
printf("prr: %d %d %d\n", prr[0], prr[1], prr[2]);
}
//myfree(arr);
return 0;
}
现在运行这段代码给我分段错误。
❯ gcc -g3 -o malloctest1 malloctest1.c
❯ ./malloctest
0x1ffffffff (nil)
[1] 45258 segmentation fault (core dumped) ./malloctest1
谁能指出错误在哪里。检查差异
尝试了 gdb 调试器并看到 head = block 不会使 head->next 到 NULL,而是打印 0x1ffffffff
你在这里有 UB 因为你没有分配足够的内存并且你在分配的内存之外写入
应该是:
int main(void)
{
int *arr, *prr;
arr = mymalloc(3 * sizeof(*arr));
prr = mymalloc(3 * sizeof(*ptr));
/* .... */
注意:如果在sizeof
中使用objects而不是
types会更好。