malloc () and free () the principle and implementation

Only dynamic application memory via malloc () and its derived function in the C language, achieved simply by calling system implemented (in linux system call is achieved through sbrk ()).

malloc () in the end we got the memory space where to? The answer is to get the space from inside the reactor. That function returns a pointer to a memory of the heap. The operating system has a linked list of free memory address of record. When the operating system receives the application program, it will traverse the linked list, and then find the first space is greater than the application heap space node, and then remove the node from the free nodes link list, and the junction point of space allocated to the program.

malloc () to allocate memory dynamically allocated at runtime, free () to release its allocated memory. malloc () allocated when the size of the incoming user, also assigned an associated for additional memory management, but the user can not see. and so,

The actual size of the management space = space + users

In the 64-bit system, malloc (0) effective memory size in bits 24, 32, 12, is accurate to say that at least so many, and these can be used in memory

Results

In addition, the heap memory block is always allocated to the block, how many bytes are not apply, the number of bytes of memory used to provide out. Heap memory block size is generally aligned with the related memory (8Byte (for 32bit system) or 16Byte (for 64bit system).

Thus, in the system 64, when the (application memory size + sizeof (struct mem_control_block))% 16 == 0, when, just to complete a full capacity allocation, but when it! = 0, the memory allocation will be more Piece.

Linux stack management system following a program is managed by the memory blocks, i.e. a lot of different sizes into the heap memory block. How these block management Nepal, such as how the query block size, how the query whether the block is being used by a program, how do you know the address of this block. In order to solve the management of blocks to memory design data structure of a memory block management, detailed data structure is as follows:

/**内存控制块数据结构,用于管理所有的内存块
* is_available: 标志着该块是否可用。1表示可用,0表示不可用
* size: 该块的大小
**/
struct mem_control_block {
    int is_available;
    int size;
};

 

 

With the management data structure of the memory block, then the organization in memory heap Ye appreciated, that is, the stack is composed of many blocks of memory, it has the following schematic:

After increasing the memory heap process

Integrated the above knowledge, you can easily think the general idea of ​​malloc implementation (). First one by one to check the heap memory is available, and if so whether it can meet the size requirements are met if the words on the direct use. When traversing all memory blocks heap, while if it is not able to meet the needs of the blocks only through system calls to the operating system, application of new memory, and then add new memory to the heap. Idea is very simple, malloc () to achieve the flowchart is as follows:

malloc () to achieve a flow chart

After reading the above ideas, it will be very easy to think of free () function of the realization of ideas, as long as the memory management block is made available on it. So that the next call to malloc () function when the memory block can be allocated as a re-allocated blocks.

Finally, paste malloc () and free () implementation code:

malloc () implementation:

/**内存控制块数据结构,用于管理所有的内存块
* is_available: 标志着该块是否可用。1表示可用,0表示不可用
* size: 该块的大小
**/
struct mem_control_block {
    int is_available;
    int size;
};

/**在实现malloc时要用到linux下的全局变量
*managed_memory_start:该指针指向进程的堆底,也就是堆中的第一个内存块
*last_valid_address:该指针指向进程的堆顶,也就是堆中最后一个内存块的末地址
**/
void *managed_memory_start;
void *last_valid_address;

/**malloc()功能是动态的分配一块满足参数要求的内存块
*numbytes:该参数表明要申请多大的内存空间
*返回值:函数执行结束后将返回满足参数要求的内存块首地址,要是没有分配成功则返回NULL
**/
void *malloc(size_t numbytes) {
    //游标,指向当前的内存块
    void *current_location;
    //保存当前内存块的内存控制结构
    struct mem_control_block *current_location_mcb;
    //保存满足条件的内存块的地址用于函数返回
    void *memory_location;
    memory_location = NULL;
    //计算内存块的实际大小,也就是函数参数指定的大小+内存控制块的大小
    numbytes = numbytes + sizeof(struct mem_control_block);
    //利用全局变量得到堆中的第一个内存块的地址
    current_location = managed_memory_start;

    //对堆中的内存块进行遍历,找合适的内存块
    while (current_location != last_valid_address) //检查是否遍历到堆顶了
    {
        //取得当前内存块的内存控制结构
        current_location_mcb = (struct mem_control_block*)current_location;
        //判断该块是否可用
        if (current_location_mcb->is_available)
            //检查该块大小是否满足
            if (current_location_mcb->size >= numbytes)
            {
                //满足的块将其标志为不可用
                current_location_mcb->is_available = 0;
                //得到该块的地址,结束遍历
                memory_location = current_location;
                break;
            }
        //取得下一个内存块
        current_location = current_location + current_location_mcb->size;
    }

    //在堆中已有的内存块中没有找到满足条件的内存块时执行下面的函数
    if (!memory_location)
    {
        //向操作系统申请新的内存块
        if (sbrk(numbytes) == -1)
            return NULL;//申请失败,说明系统没有可用内存
        memory_location = last_valid_address;
        last_valid_address = last_valid_address + numbytes;
        current_location_mcb = (struct mem_control_block)memory_location;
        current_location_mcb->is_available = 0;
        current_location_mcb->size = numbytes;
    }
    //到此已经得到所要的内存块,现在要做的是越过内存控制块返回内存块的首地址
    memory_location = memory_location + sizeof(struct mem_control_block);
    return memory_location;
}

 

free () implementation:

/**free()功能是将参数指向的内存块进行释放
*firstbyte:要释放的内存块首地址
*返回值:空
**/
void free(void *firstbyte)
{
    struct mem_control_block *mcb;
    //取得该块的内存控制块的首地址
    mcb = firstbyte - sizeof(struct mem_control_block);
    //将该块标志设为可用
    mcb->is_available = 1;
    return;
}

 

 

 reference:

      https://blog.csdn.net/c1s2p3/article/details/50522185

      https://blog.csdn.net/qq_29350001/article/details/70213602

      https://www.cnblogs.com/debuging/p/3158147.html

Published 407 original articles · won praise 150 · views 380 000 +

Guess you like

Origin blog.csdn.net/ds1130071727/article/details/102551928