以下 custommalloc 程序如何以不同的方式运行

问题描述 投票:0回答:1

我正在尝试编写一个自定义 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

谁能指出错误在哪里。检查差异

enter image description here

尝试了 gdb 调试器并看到 head = block 不会使 head->next 到 NULL,而是打印 0x1ffffffff

c linux malloc
1个回答
0
投票

你在这里有 UB 因为你没有分配足够的内存并且你在分配的内存之外写入

应该是:

int main(void)
{
    int *arr, *prr;
    arr = mymalloc(3 * sizeof(*arr));
    prr = mymalloc(3 * sizeof(*ptr));
   
    /* .... */

注意:如果在sizeof中使用objects而不是

types
会更好。

© www.soinside.com 2019 - 2024. All rights reserved.