zoukankan      html  css  js  c++  java
  • new与malloc

    首先将new与malloc的区别总结如下:

    1 new可以自动计算需要分配多大的内存,而malloc必须指明。

    2 new返回的指针是有类型的,malloc返回void*类型的指针。

    3 new在分配内存的同时会调用构造函数。

    4 new是c++运算符,malloc是标准库函数。

    由于3所述,malloc在c++中无法满足为非内部对象分配内存的需求。

        那么malloc是如何进行内存分配的呢?它将内存块连接为一个链表。调用malloc函数时,它沿链表寻找一个大到足以满足用户请求所需要的空闲内存块。然后,将该内存块传给用户(如果该内存块比用户申请的内存大很多,可进行分割),并将该内存块标记为已用。(free的过程待补充)

        malloc具体实现参考:

    http://blog.codinglabs.org/articles/a-malloc-tutorial.html

    该文对Linux系统内存相关知识的介绍也十分清楚。现将其malloc实现简单总结如下:

        内存按块划分,每个块由meta区和数据区组成,meta区记录数据区的大小、是否空闲并指向下一个内存块。数据区是真实分配的内存,malloc返回给用户的就是数据区的首地址。首先定义表示内存块的数据结构:

    typedef struct s_block* t_block;
    struct s_block
    {
        size_t size;
        int free;
        t_block next;
        int padding;
        char data[1];
    
    };

        然后实现查找内存块的find_block,传入需要分配的内存大小,返回找到的指向内存块的指针:

    t_block find_block(t_block* last, size_t s)
    {
        t_block b = first_block;
        while (b&&!(b->free && b->size >= s))
        {
                *last = b;
                b = b->next;
        }
        return b;
    }

    从头开始搜索链表,对于不符合条件的节点,last立即跟踪,遇到符合条件的节点或空节点循环结束。last是为了当遍历完链表没有符合条件的节点,即b=NULL时,记录最后一个节点,方便后面做扩展。做扩展的代码如下:

    #define BLOCKSIZE 24
    t_block extend_block(t_block last, size_t s)
    {
        t_block b = sbrk(0);
        if (sbrk(s + BLOCKSIZE) == (void*)-1)
            return NULL;
        b->size = s;
        b->free = 0;
        b->next = last->next;
        last->next = b;
        return b;
    }

    即用系统调用sbrk()在堆上新找到个节点,并将其接到原链表。malloc还要做的一个工作就是如果内存块比较大,将其分给一个申请了很小内存空间的用户会显得很浪费,此时malloc应将该内存块分割,将剩余的内存作为新节点放在链表上:

    void split_block(t_block b, size_t s)
    {
        t_block newb;
        newb = (t_block)b->data + s;
        newb->size = b->size - s - BLOCKSIZE;
        newb->free = 1;
        newb->next = b->next;
        b->next = newb;
        b->size = s;
    }

        有了以上的函数,malloc就可以简单的实现如下:

    void* first_block=NULL;
    
    void* malloc(size_t size)
    {
        size_t s;
        s = align(size); 
        t_block b=first_block;
        t_block last;
        if (b)
        {
            b = find_block(&last, s);
            if (b)
            {
                if (b->size >= (s + BLOCKSIZE + 8))
                    split_block(b, s);
                b->free = 0;
            }
            else
            {
                b = extend_block(last, s);
            }
        }
        else
        {
            b = extend_block(NULL, s);
            first_block = b;
    
        }
        return b;
    }
  • 相关阅读:
    《就这》
    《我傻了》
    nginx配置本地https方法
    idea插件开发——Generate Resource SQL
    Java本地命令执行
    自定义类加载器和UrlClassLoader
    类加载器学习
    IO流学习
    Java
    static关键字
  • 原文地址:https://www.cnblogs.com/lulu10922/p/5807373.html
Copyright © 2011-2022 走看看