首页 > 系统相关 >C++---内存管理

C++---内存管理

时间:2024-09-09 13:22:47浏览次数:14  
标签:malloc C++ --- 空间 内存 operator new delete

1 C/C++内存分布

栈区:由编译器自动分配和释放,存放运行时候的局部变量,函数参数,返回数据,返回地址。

堆区:一般由程序员自己分配,然后自己释放,例如栈的实现malloc开辟的数组空间。

数据段(静态区):存放全局变量,静态数据,常量,程序结束后自动释放。

代码段(常量区):存放常量字符串和可执行代码,程序结束自动释放。

2 C语言中动态内存管理方式:malloc/calloc/realloc/free

malloc:开辟空间,不初始化 (int*)malloc(sizeof(int)):开辟一个int大小的空间。

calloc:开辟空间并把每个字节初始化为0。(int*)calloc(4,sizeof(int)):开辟4个int大小的空间。

realloc(用于扩容):在内存找一段连续大小的空间,将传入的指针指向的内存内的字节全部拷贝过来,然后释放原指针空间,再把新大小的空间指针返回。(int*)realloc(_ptr,sizeof(int)*10)。

free:释放一段连续空间。free(_ptr),释放完之和_ptr为野指针,一般需要_ptr=NULL。

3 C++内存管理实现

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

在对内置类型开辟空间时new和malloc实质上是没什么区别的,但在对自定义类对象进行空间开辟时候,new和malloc的区别在于malloc只负责开辟空间不会进行初始化,而new开辟空间的同时会调用自定义类内的构造函数进行初始化。

 

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意:匹配起来使用。

new/delete和malloc/free最大的区别在于,new/delete开辟空间会调用构造函数,结束会调用析构函数。而malloc/free不会。

operator new与operator delete

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

/*
operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,
尝试执行空
间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。
*/
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
    // try to allocate size bytes
    void *p;
    while ((p = malloc(size)) == 0)
    if (_callnewh(size) == 0)
    {
        // report no memory
        // 如果申请内存失败了,这里会抛出bad_alloc 类型异常
        static const std::bad_alloc nomem;
        _RAISE(nomem);
    }
    return (p);
}
/*
operator delete: 该函数最终是通过free来释放空间的
*/
void operator delete(void *pUserData)
{
    _CrtMemBlockHeader * pHead;
    RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
    if (pUserData == NULL)
        return;
    _mlock(_HEAP_LOCK); /* block other threads */
    __TRY
    /* get a pointer to memory block header */
    pHead = pHdr(pUserData);
    /* verify block type */
    _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
    _free_dbg( pUserData, pHead->nBlockUse );
    __FINALLY
    _munlock(_HEAP_LOCK); /* release other threads */
    __END_TRY_FINALLY
    return;
}
/*
free的实现
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)

通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

说白了operator new就是new子过程,new就等价于operator new之和在调用构造函数。而operator new在程序设计上又是由malloc为基础,区别于malloc的就是malloc申请空间失败之和返回值是0。而operator new申请空间失败后是直接抛异常。

定位new表达式

定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。

我们用malloc为p3开辟一个结构体大小的空间后,成员变量并没有初始化,但由于成员变量为private修饰的在外不可访问,这时候就可以利用定位new去进行初始化。

定位new格式为new(变量)+类名(初始化)。

malloc/free与new/delete的区别

共同点是都在堆上申请空间,需要用户手动释放。

区别是malloc/free是函数而new/delete是操作符。

malloc/free使用时候只开辟空间和销毁空间,而new/delete开辟空间会调用构造函数初始化,销毁空间会调用析构函数。

malloc返回值是void*使用时候需要强转类型,而new不用,编译器自动识别。

malloc申请空间失败返回的是NULL,而new申请空间失败会抛异常。

内存泄露

什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。 

内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。

标签:malloc,C++,---,空间,内存,operator,new,delete
From: https://blog.csdn.net/m0_63703622/article/details/142055840

相关文章

  • C++--static成员和友元
    1static声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化静态定义的成员变量在类外定义,变量类型类名::变量名=value的形式。此外,static还可以在类里面定义......
  • 青少年编程与数学 01-010 青少年成长管理 第六章 专业 4_1 如何选择
    青少年编程与数学01-010青少年成长管理第六章专业4_1如何选择本章摘要:第一节如何选择一、行业、职业、学科、专业二、专业选择的时效性三、专业选择的一般步骤(一)**自我探索**:(二)**市场调研和社会需求分析**:(三)**获取教育咨询和专业信息**:(四)**实践体验**:(五)**做出决策......
  • 青少年编程与数学 01-010 青少年成长管理 第六章 专业 4_2 职业选择
    青少年编程与数学01-010青少年成长管理第六章专业4_2职业选择第二节职业选择一、什么是职业二、何时选择职业(一)尽早选择(二)大学毕业时选择(三)被动选择三、就业四、失业(一)什么是失业(二)永久性失业(三)终身失业(四)关注失业统计数据五、职业的一般分类1.按照工作性质分......
  • 第六章-类与对象
    class类名称:    类的属性(定义在类中的成员变量)    类的行为(定义在类中的函数,也就是成员方法)举例:classStudent:name=Noneplace=Noneage=Nonedefsay_hi(self):print(f"你好,我是{self.name}")stu1=Student()st......
  • vue打印模版模块,使用vue-plugin-hiprint插件搭建过程
    文章目录概要安装插件引入全局样式引入字体图标库完整demo解析-保存模版解析-左侧的自定义组件解析-视图容器解析-打印文件地址概要项目中,我们可能需要实现打印的需求功能,而打印时,用户可以先去编辑打印模版,这样再其他模版,只需要提供数据,就可以使用模......
  • 基于过程干预的课程成绩预警系统的设计与实现-计算机毕业设计源码+LW文档
    摘 要随着学生数量的不断增加,传统的学生管理方式已难以满足高效、准确的数据处理需求。传统的成绩管理方式往往只关注结果,而忽略了学生学习过程中的问题和困难。这种预警系统旨在通过对学生学习过程的实时监测和数据分析,及时发现学生的学习问题,并通过个性化的干预措施,帮助学生调......
  • 2025秋招NLP算法面试真题(十九)-大模型分布式训练题目
    分布式训练题目1.理论篇1.1训练大语言模型存在问题?计算资源需求**:**训练大型语言模型需要大量的计算资源,包括高端GPU、大量的内存和高速存储器。这可能限制了许多研究人员和组织的训练能力,因为这些资源通常很昂贵。数据需求**:**训练大型语言模型需要大规模的数......
  • 2025秋招NLP算法面试真题(十八)-大模型训练数据格式常见问题
    1.SFT(有监督微调)的数据集格式?对于大语言模型的训练中,SFT(SupervisedFine-Tuning)的数据集格式可以采用以下方式:输入数据:输入数据是一个文本序列,通常是一个句子或者一个段落。每个样本可以是一个字符串或者是一个tokenized的文本序列。标签数据:标签数据是与输入数据对应的......
  • 2025秋招计算机视觉面试题(十二) -理清深度学习优化函数发展脉络
    问题深度学习中有很多优化函数,常见的那些你还记得它的定义以及优缺点吗?背景知识深度学习网络训练中,有很多可供选择的优化函数如SGD、Adam等等,到底用哪个好呢?其实这个问题没有确切的答案,优化函数是需要配合损失函数使用的,说白了,优化函数也是一种超参数,是需要尝试的,哪个效......
  • 训练框架技术序列一:Megtron-LLM架构源码
    本文章涉及的Megatron-llm的XMind思维导图源文件和PDF文件,可在网盘下载:https://pan.baidu.com/s/1xRZD-IP95y7-4Fn0C_VJMg提取码:qxff一、引言Megatron-Core是一个基于PyTorch的开源库,专为在NVIDIAGPU上高效训练大型语言模型(LLMs)而设计。它提供了一系列GPU优化的训......