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

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

(0)
上一篇 2022年5月7日 下午11:40
下一篇 2022年5月7日 下午11:40


相关推荐

  • gfortran在linux下安装

    gfortran在linux下安装在 http gfortran meteodat ch download x86 64 nightlies gcc trunk tar xz 下载 gfortran nbsp wgethttp gfortran meteodat ch download x86 64 nightlies gcc trunk tar xz nbsp nbsp xz dgcc trunk tar xztar

    2026年3月17日
    2
  • W3C标准与规范「建议收藏」

    W3C标准与规范「建议收藏」W3C标准,即一系列标准的集合,他的本质是结构标准语言。就像平时使用的HTML、CSS等都需要遵守这些标准。万维网联盟创建于1994年,是web技术领域最具权威和影响力的国际中立性技术标准机构。它有效促进了web技术相互之间的兼容。就像网页是由三部分组成:结构、表现和行为。那么他对应的标准也分三方面:1.结构化标准语言:HTML。可扩展标记语言(XML):最初设计目的是弥补HTML的不

    2025年12月12日
    6
  • Windows下在pycharm中安装pytorch

    Windows下在pycharm中安装pytorch打开 pycharm 点击左上角的 file settings 找到 ProjectInter 点击 号 点击 ManageReposi 输入下面的两个网址即可 点击 ok 保存 https pypi tuna tsinghua edu cn simple https mirrors aliyun com pypi simple 然后点击搜索 pytorch 点击安装即可 但是我安装的时候显示错误 系统提示我在 terminal 中用 pi

    2026年3月27日
    2
  • excel右键不出菜单_哈希校验码下载

    excel右键不出菜单_哈希校验码下载推荐阅读:这套Github上40K+star学习笔记,可以帮你搞定95%以上的Java面试毫不夸张的说,这份SpringBoot学习指南能解决你遇到的98%的问题给跪了!这套万人期待的SQL成神之路PDF,终于开源了最近遇到这么一件事:我在官网下载软件安装包,准备安装的时候被提示说是有病毒,不让安装。当时我就纳闷了,这官网下载的文件怎么会有病毒呢?于是我找到官网标注的文件Hash…

    2025年9月11日
    7
  • java vo 什么意思_在Java中VO , PO , BO , QO, DAO ,POJO是什么意思

    java vo 什么意思_在Java中VO , PO , BO , QO, DAO ,POJO是什么意思在Java中VO,PO,BO,DAO,POJO是什么意思最近在项目中,遇到VO,我的天。。。那就一起学习回忆一下首先简单说明下:O/RMapping是ObjectRelationalMapping(对象关系映射)的缩写。简单来说,就是将对象和关系数据库绑定,用对象来表示关系数据。JavaWEB三层架构咱们更需要熟练使用VO:值对象(ValueObject)用new关键字创建…

    2022年5月8日
    85
  • lamp环境下phpwind,wordpress,discuz论坛的搭建全过程

    lamp环境下phpwind,wordpress,discuz论坛的搭建全过程phpwind,wordpress,discuz3大论坛群英聚会目前世界最流行的企业建站方式是LAMP(Linux+Apache+MySQL+PHP),即使用Linux作为操作系统,Apache作为Web服务器,MySQL作为数据库,PHP作为服务器端脚本解释器。这四个软件都是遵循GPL的开放源码软件,它们安全、稳定、快速、功能强大…

    2026年1月19日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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