malloc函数实现过程

malloc函数实现过程在C语言中,要进行动态内存的开辟就需要使用到malloc函数,在C++中使用的new关键字的基层也是调用了malloc函数,可见malloc函数的重要性,这个就浅析一下malloc的实现过程。本文的测试环境是win10+vs2015。首先先看看malloc函数怎么去调用//malloc函数原型//void*malloc(size_tsize);//(MSDN中的定义)type

大家好,又见面了,我是你们的朋友全栈君。

在C语言中,要进行动态内存的开辟就需要使用到malloc函数,在C++中使用的new关键字的基层也是调用了malloc函数,可见malloc函数的重要性,这个就浅析一下malloc的实现过程。
本文的测试环境是win10+vs2015。

首先先看看malloc函数怎么去调用

// malloc函数原型
// void *malloc( size_t size );//(MSDN中的定义)
type* temp=(type*)malloc(sizeof(type*n));
// type表示数据类型;
// n表示需要创建几个该类型的成员
// sizeof(type*n)表示成员所占空间

有函数原型可知

  • malloc函数返回值是void*,所以实际上是用的时候都将其进行了强制转换
  • malloc函数的传参是size_t类型的,在vs2015中的定义是
    typedef unsigned int size_t;
    表示它是无符号整数类型
    sizeof关键返回值是size_t,所以不会冲突

重点内容
malloc函数申请空间的操作步骤:

  1. 对堆进行加锁
  2. 在正式申请空间之前,对堆进行校验
  3. 检测申请内存块的类型
  4. 检测内存空间是否充足,不够设置错误信息,返回NULL,否则进行5
  5. 检测块的类型
  6. 计算本次所要申请的内存块的总字节数
  7. 按照计算的总字节数申请内存,底层真正向堆申请空间的是HeapAlloc函数
  8. 检测是否申请成功,如果申请失败设置错误信息,返回NULL,否则执行9
  9. 修改请求次数和目前申请的总字节数
  10. 将新申请的内存块的新节点头插到双向链表中
  11. 给该结点对应的结构体赋值
  12. 填充空间
  13. 获取申请内存块中存放有效数据的真正位置
  14. 对堆进行解锁
  15. 返回有效数据区域的地址

malloc函数的具体实现过程

// 该段代码拷贝于vs2015的malloc.h
// malloc.h
#pragma once
#define _INC_MALLOC

#include <corecrt.h>
#include <corecrt_malloc.h>

_CRT_BEGIN_C_HEADER

// 查看是win32还是win64的平台

#ifdef _WIN64
    #define _HEAP_MAXREQ 0xFFFFFFFFFFFFFFE0
#else
    #define _HEAP_MAXREQ 0xFFFFFFE0
#endif

// 定义相关的宏常量
#define _HEAPEMPTY (-1)//堆空
#define _HEAPOK (-2)
#define _HEAPBADBEGIN (-3)
#define _HEAPBADNODE (-4)
#define _HEAPEND (-5)//堆尾
#define _HEAPBADPTR (-6)
#define _FREEENTRY 0
#define _USEDENTRY 1

//定义一个结构体
typedef struct _heapinfo
{
    int* _pentry;
    size_t _size;
    int _useflag;
} _HEAPINFO;

//定义相关宏
#define _mm_free(a) _aligned_free(a)
#define _mm_malloc(a, b) _aligned_malloc(a, b)

// 未完待续。。。

_Ret_notnull_ _Post_writable_byte_size_(_Size)
void* __cdecl _alloca(_In_ size_t _Size);



#if !defined __midl && !defined RC_INVOKED

    _ACRTIMP intptr_t __cdecl _get_heap_handle(void);

    _Check_return_
    _DCRTIMP int __cdecl _heapmin(void);

    #if defined _DEBUG || defined _CRT_USE_WINAPI_FAMILY_DESKTOP_APP || defined _CORECRT_BUILD
        _ACRTIMP int __cdecl _heapwalk(_Inout_ _HEAPINFO* _EntryInfo);
    #endif

    #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP
        _Check_return_ _DCRTIMP int __cdecl _heapchk(void);
        _DCRTIMP int __cdecl _resetstkoflw(void);
    #endif

    #define _ALLOCA_S_THRESHOLD 1024
    #define _ALLOCA_S_STACK_MARKER 0xCCCC
    #define _ALLOCA_S_HEAP_MARKER 0xDDDD

    #ifdef _WIN64
        #define _ALLOCA_S_MARKER_SIZE 16
    #else
        #define _ALLOCA_S_MARKER_SIZE 8
    #endif

    _STATIC_ASSERT(sizeof(unsigned int) <= _ALLOCA_S_MARKER_SIZE);


    #pragma warning(push)
    #pragma warning(disable:6540)

    __inline void* _MarkAllocaS(_Out_opt_ __crt_typefix(unsigned int*) void* _Ptr, unsigned int _Marker)
    {
        if (_Ptr)
        {
            *((unsigned int*)_Ptr) = _Marker;
            _Ptr = (char*)_Ptr + _ALLOCA_S_MARKER_SIZE;
        }
        return _Ptr;
    }

    __inline size_t _MallocaComputeSize(size_t _Size)
    {
        size_t _MarkedSize = _Size + _ALLOCA_S_MARKER_SIZE;
        return _MarkedSize > _Size ? _MarkedSize : 0;
    }

    #pragma warning(pop)

#endif



#ifdef _DEBUG

    #ifndef _CRTDBG_MAP_ALLOC
        #undef _malloca
        #define _malloca(size) \
            __pragma(warning(suppress: 6255 6386))                                       \
            (_MallocaComputeSize(size) != 0                                              \
                ? _MarkAllocaS(malloc(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER) \
                : NULL)
    #endif

#else

    #undef _malloca
    #define _malloca(size) \
        __pragma(warning(suppress: 6255 6386))                                             \
        (_MallocaComputeSize(size) != 0                                                    \
            ? (((_MallocaComputeSize(size) <= _ALLOCA_S_THRESHOLD)                         \
                ? _MarkAllocaS(_alloca(_MallocaComputeSize(size)), _ALLOCA_S_STACK_MARKER) \
                : _MarkAllocaS(malloc(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER))) \
            : NULL)

#endif



#if defined __midl && !defined RC_INVOKED
#elif defined _DEBUG && defined _CRTDBG_MAP_ALLOC
#else

    #undef _freea

    #pragma warning(push)
    #pragma warning(disable: 6014)
    __inline void __CRTDECL _freea(_Pre_maybenull_ _Post_invalid_ void* _Memory)
    {
        unsigned int _Marker;
        if (_Memory)
        {
            _Memory = (char*)_Memory - _ALLOCA_S_MARKER_SIZE;
            _Marker = *(unsigned int*)_Memory;
            if (_Marker == _ALLOCA_S_HEAP_MARKER)
            {
                free(_Memory);
            }
            #ifdef _ASSERTE
            else if (_Marker != _ALLOCA_S_STACK_MARKER)
            {
                _ASSERTE(("Corrupted pointer passed to _freea", 0));
            }
            #endif
        }
    }
    #pragma warning(pop)

#endif



#if !__STDC__
    #define alloca _alloca
#endif



_CRT_END_C_HEADER
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140036.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 两位数活多位乘法的计算编程

    两位数活多位乘法的计算编程代码编写;OptionBase1PrivateSubCommand1_Click()DimMAsStringDimNAsStringM=Trim(Text1.Text)N=Trim(Text2.Text)DimNumber1()AsByteDimNumber2()AsByteReDimNumber1(Len(M))R

  • CI框架 — URL

    CI框架 — URL

  • 2022-Java面试宝典收藏版

    2022-Java面试宝典收藏版Java基础目录前言一、基础篇1.1.Java语言有哪些特点1.2.面向对象和面向过程的区别1.3.八种基本数据类型的大小,以及他们的封装类1.4.标识符的命名规则。1.5.instanceof关键字的作用1.6.Java自动装箱与拆箱1.7.重载和重写的区别1.8.equals与==的区别1.9.Hashcode的作用1.10.String、StringStringBuffer和StringBuilder的区别是什么?1.11.ArrayList和linkedLi

  • 用Java IO流实现下载文件

    用Java IO流实现下载文件  @RequestMapping(value="download")   publicStringdownload(HttpServletResponseresponse,Modelmodel){             //通过文件名找出文件的所在目录      StringURL="D:/one/two.txt";      //得到要下载的文件…

  • oracle dba教程视频_数据库中的DBA

    oracle dba教程视频_数据库中的DBA我机器上只有一部分的版本:http://v.youku.com/v_show/id_XMTk3MTgzMzI=.htmlhttp://www.ixdba.net/article/b3/1317.htmlhttp://itboba.com/taxonomy/term/620http://v.youku.com/v_playlist/f2972170o1p9.html

    2022年10月25日
  • java socket通讯中文乱码问题

    java socket通讯中文乱码问题话不多说上代码publicvoidrun(){//客户端一连接就可以写数据给服务器了newsendMessThread().start();super.run();try{//读Sock里面的数据InputStreams=socket.getInputStream();byte[]buf=newbyte[1024];

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号