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)


相关推荐

  • 35岁以上的IT人士如果有一天被公司裁员了,该怎么办?

    35岁以上的IT人士如果有一天被公司裁员了,该怎么办?我觉得裁员和年龄无关,和本人的技能,工作态度,处事规则有关系。大家都知道华为裁员比例厉害,特别是对35岁以上的,会感到中年危机。但是我几个在华为的同学,都到了40岁了工作依然好好的,也没有见谁被裁掉。如果在工作中保持积极的态度,做事主动,平常多学习,和同事,领导的关系都不错,那么也不会被裁掉。作为已经到而立之年的中年人,给大家一点建议吧。在工作和生活中时刻保持乐观的心态,做事积极主动,多想多思考,与同事和领导友好相处,尽量让自己成为不可替代的人。那么你就不会被裁掉,也不会有中年危机。…

  • L2正则化的作用(l1正则化特点)

    0正则化的作用正则化的主要作用是防止过拟合,对模型添加正则化项可以限制模型的复杂度,使得模型在复杂度和性能达到平衡。常用的正则化方法有L1正则化和L2正则化。L1正则化和L2正则化可以看做是损失函数的惩罚项。所谓『惩罚』是指对损失函数中的某些参数做一些限制。L1正则化的模型建叫做Lasso回归,使用L2正则化的模型叫做Ridge回归(岭回归。但是使用正则化来防止过拟合的原理是什么?L1和L…

  • 配置监听_1521端口占用问题

    配置监听_1521端口占用问题声明:原创作品,出自“深蓝的blog”博客,欢迎转载,转载时请务必注明出处,否则追究版权法律责任。深蓝的blog: 前提回现修改了主机名,由hyldb修改为hyl。问题现象配置监听,警告提示,如下所示:解决方法1、检查1521端口[root@hyl~]#netstat-a–查看端口占用情况,查明1521端口并未被占用ActiveInte

  • 微服务架构-实现技术之具体实现工具与框架6:Spring Cloud Hystrix原理与注意事项

    微服务架构-实现技术之具体实现工具与框架6:Spring Cloud Hystrix原理与注意事项目录一、SpringCloudHytrix概述和设计目标(一)SpringCloudHytrix基本概述(二)SpringCloudHytrix概述设计目标二、SpringCloudHytrix解决的主要内容(一)隔离(线程池隔离和信号量隔离)1.线程和线程池线程隔离的好处:线程隔离的缺点2.信号量隔离(Semaphores)(二)优雅的降级…

  • pycharm导入cv2包_pycharm安装cv2失败

    pycharm导入cv2包_pycharm安装cv2失败windows下1.情况一:已在官网下载opencv无需下载,只需要导入环境即可;1.首先,在opencv目录中找到cv2文件夹:opencv3.4.8\opencv\build\python\cv2复制文件夹2.找到Python的根路径,在项目列表可查看(以实际显示的路径为主):在python.exe目录下找到Lib\site-packages,粘贴文件夹2.情况二:下载并…

  • 坐标拾取系统定位_cad移动到绝对坐标

    坐标拾取系统定位_cad移动到绝对坐标usingUnityEngine;usingUnityEngine.UI;usingSystem.Collections;publicclasstransforms:MonoBeh

发表回复

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

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