06 内存管理

目录

  1. c/c++内存分布
  2. c语言中动态内存管理方式
  3. c++中动态内存管理方式
  4. operator new与operator delete函数
  5. new和delete的实现原理
  6. 定位new表达式(placement-new)
  7. 常见题

1. c/c++内存分布

看一段代码

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{static int staticVar = 1;int localVar = 1;int num1[10] = { 1, 2, 3, 4 };char char2[] = "abcd";const char* pChar3 = "abcd";int* ptr1 = (int*)malloc(sizeof(int) * 4);int* ptr2 = (int*)calloc(4, sizeof(int));int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);free(ptr1);free(ptr3);
}
1. 选择题:选项: A.栈  B.堆  C.数据段(静态区)  D.代码段(常量区)globalVar在哪里?____   staticGlobalVar在哪里?____staticVar在哪里?____   localVar在哪里?____num1 在哪里?____char2在哪里?____   *char2在哪里?___pChar3在哪里?____      *pChar3在哪里?____ptr1在哪里?____        *ptr1在哪里?____
2. 填空题:sizeof(num1) = ____; sizeof(char2) = ____;      strlen(char2) = ____;sizeof(pChar3) = ____;     strlen(pChar3) = ____;sizeof(ptr1) = ____;
3. sizeof 和 strlen 区别?
  1. 选择题:
    选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
    globalVar在哪里?C__ staticGlobalVar在哪里?C__
    staticVar在哪里?C__ localVar在哪里?A__
    num1 在哪里?A__

    char2在哪里?A__ *char2在哪里?A___
    pChar3在哪里?A__ *pChar3在哪里?D__
    ptr1在哪里?A__ *ptr1在哪里?B__

  2. 填空题:
    sizeof(num1) = 40__;
    sizeof(char2) = 5__; strlen(char2) = 4__;
    sizeof(pChar3) = 4/8__; strlen(pChar3) = 4__;
    sizeof(ptr1) = 4/8__;

在这里插入图片描述

【说明】
1.栈又叫堆栈-非静态局部变量/函数参数/返回值等等,栈是向下增长的
2.内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口,创建共享内存,叫做进程通信
3.堆用于程序运行时动态内存分配,堆是上增长的
4.数据段–存放全局数据和静态数据
5.代码段–可执行的代码/只读常量

2. c语言中动态内存管理方式

void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗?
free(p3 );
}

上面的p2不需要free,因为realloc扩容后原空间会自动释放,再次free会崩溃

malloc/calloc/realloc的区别
malloc申请一段空间,默认值。calloc申请空间赋初始值。realloc对一段已存在的空间扩容,本地或异地

3. c++内存管理方式

c语言内存管理可以继续使用,但有的地方无能为力,主要对于自定义类型。而且使用起来麻烦,c++提出了自己的内存管理方式

3.1 new/delete操作内置类型

void Test()
{// 动态申请一个int类型的空间int* ptr4 = new int;// 动态申请一个int类型的空间并初始化为10int* ptr5 = new int(10);// 动态申请10个int类型的空间int* ptr6 = new int[3];delete ptr4;delete ptr5;delete[] ptr6;
}

申请和释放单个元素空间,用new和delete.申请连续的空间,用new[]和delete[],匹配使用

3.2 new和delete操作自定义类型

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}
private:int _a;
};
int main()
{// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间
还会调用构造函数和析构函数A* p1 = (A*)malloc(sizeof(A));A* p2 = new A(1);free(p1);delete p2;// 内置类型是几乎是一样的int* p3 = (int*)malloc(sizeof(int)); // Cint* p4 = new int;
free(p3);
delete p4;A* p5 = (A*)malloc(sizeof(A)*10);A* p6 = new A[10];free(p5);delete[] p6;return 0;
}

注意:在申请自定义类型的空间时,new会自动调用构造函数,delete会调用析构函数,malloc和free不会

4. operator new和operator delete函数

4.1 概念

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_FINALLYreturn;
}
/*
free的实现
*/
#define   free(p)               _free_dbg(p, _NORMAL_BLOCK)

通过上述两个全局函数的实现直到,operator new实际也是通过malloc申请空间,如果成功直接返回,否则就抛异常。operator delete最终是通过free来释放空间

5. new和delete的实现原理

5.1 内置类型

如果申请的是内置类型空间,new和malloc这些相似,不同的是new[]和delete[]申请释放连续空间,new申请失败时会抛异常,malloc会返回空

5.2 自定义类型

  • new原理
    1.调用operator new函数申请空间
    2.在申请的空间上执行构造函数,完成对象的构造
  • delete的原理
    1.在申请的空间上执行析构函数,完成对象的资源清理工作
    2.调用operator delete函数释放空间
  • new T[N]的原理
    1.调用operator new[]函数,实际调用operator new完成N个对象申请空间
    2.在申请的空间上执行N次构造函数
  • delete的原理
    1.在申请的空间上执行N次析构函数,完成N个对象的资源清理工作
    2.调用operator delete[]函数,实际调用operator delete完成N个对象申请空间

注意
申请空间的操作符必须配合使用,不能互相混着用
比如下面的操作会崩溃

int main()
{int* p1 =new int[5];free(p1);delete p1;delete[] p1;return 0;
}

原因是new申请的连续空间会用前4个字节记录申请的长度,free的p1地址会崩溃,规范写法会往前4个字节取堆的大小来释放,并决定调用几次析构函数

在这里插入图片描述

6. 定位new表达式(placement-new)

定位new表达式是在已分配的空间调用构造函数初始化一个对象

使用格式:
new(place_address)type或者new(place_address)type(initializer-list)
place_address必须是一个指针,initializer-list是初始化列表

使用场景:
一般配合内存池使用,内存池是向内存中申请一块较大的空间,后面再需要空间直接从内存中获取,用内存池管理空间,不够了继续申请。内存池分配的内存没有初始化,如果是自定义类型的对象,需要使用new的定义表达式进行显示构造函数初始化

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}
private:int _a;
};
// 定位new/replacement new
int main()
{// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没
有执行A* p1 = (A*)malloc(sizeof(A));new(p1)A;  // 注意:如果A类的构造函数有参数时,此处需要传参p1->~A();free(p1);A* p2 = (A*)operator new(sizeof(A));new(p2)A(10);p2->~A();operator delete(p2);return 0;
}

7. 常见题

7.1 malloc/free和new/delete的区别

共同点都是从堆上申请空间,并且需要手动释放
不同点:
1.malloc和free是函数,new和delete是操作符
2.malloc申请的空间不会初始化,new可以初始化
3.malloc申请空间时,需要手动计算大小并传递,new只需在其后跟上空间类型即可,如果多个对象,[]中指定对象个数
4.mallo返回值为void*,使用时强转,new不需要,new后面有空间类型
5.malloc申请失败返回NULL,必须判空,new不需要,捕获异常
6.申请自定义类型时,malloc和free只会开辟空间.而new和delete会调用构造和析构函数完成初始化和清理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/484935.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FSQ: FINITE SCALAR QUANTIZATION: VQ-VAE MADE SIMPLE

Paper name FINITE SCALAR QUANTIZATION: VQ-VAE MADE SIMPLE Paper Reading Note Paper URL: https://arxiv.org/abs/2309.15505 Code URL: (官方 jax 实现) https://github.com/google-research/google-research/tree/master/fsq(pytorch 实现) https://github.com/luci…

教你用Appium搭建Android自动化测试框架(详细教程)

如题&#xff0c;本文附有仓库地址以及代码&#xff0c;目录如下&#xff1a; 1.下载安装appium 2.配置并使用appium 3.配置工程 一、下载安装appium 下载appium-desktop的mac版本&#xff0c;我选择用1.17.1版本&#xff0c;最新的版本1.22.0&#xff0c;拆分一个桌面应用…

2.22作业

作业要求&#xff1a; 程序代码&#xff1a; #include<myhead.h>int num 520; pthread_mutex_t mutex;void* task1(void* arg) {pthread_mutex_lock(&mutex);num 1314;sleep(3);printf("task1:num %d\n", num);pthread_mutex_unlock(&mutex); }voi…

医药之链:基于Django的智能药品管理系统

框架 Python 3.7 django 3.2.13 Bootstrap&#xff08;前端&#xff09; sqlite&#xff08;数据库&#xff09;导包 pip install django3.2.13 pip install pandas pip install xlwt环境搭建 登录 zfx 123456

iOS 不用VOIP也可以实现微信来电邀请推送持续响铃震动及及时来电取消

iOS 不用VOIP也可以实现微信来电邀请推送持续响铃震动及及时来电取消 前言一 、关于NotificationServiceExtension1. 创建2. 推送机制3. API 实例方法二、 APNS Push Payload2. 来电邀请2. 来电取消三、数据共享3. 配置共享域四 知识点就到这里,下面是主要代码4. 1 Notificati…

C++ 八数码问题理解 `IDA*` 算法原则:及时止损,缘尽即散

1.前言 八数码是典型的状态搜索案例。如字符串转换问题、密码锁问题都是状态搜索问题。 状态搜索问题指由一种状态转换到到最终状态&#xff0c;求解中间需要经过多少步转换&#xff0c;或者说最小需要转换多少步&#xff0c;或者说有多少种转换方案。本文和大家聊聊八数码问…

如何在Shopify 创建Mega Menu

在Shopify上创建Mega Menu可以通过以下步骤完成&#xff1a; 1. 选择适合的主题 首先&#xff0c;选择一个适合的主题&#xff0c;因为不是所有的Shopify主题都支持Mega Menu。确保选择一个具有自定义菜单功能的主题&#xff0c;或者您可以使用Shopify App Store中的应用程序来…

(十三)【Jmeter】线程(Threads(Users))之tearDown 线程组

简述 操作路径如下: 作用:在正式测试结束后执行清理操作,如关闭连接、释放资源等。配置:设置清理操作的采样器、执行顺序等参数。使用场景:确保在测试结束后应用程序恢复到正常状态,避免资源泄漏或对其他测试的影响。优点:提供清理操作,确保测试环境的整洁和可重复性…

mysql索引问题

今天在工作写项目的时候&#xff0c;突然发现很多地方没有加索引&#xff0c;然后我就去加了&#xff0c;查了不少资料&#xff0c;捡起来了不少东西&#xff0c;来简单聊一聊&#xff0c;工作中最重要的一个细节&#xff1a;索引 mysq的存储结构 首先要聊一聊mysql的存储模式…

Docker镜像和容器

1.Docker的架构和底层技术 Docker提供了一个开发、打包、运行APP&#xff08;应用application&#xff09;的平台把APP和底层infrastructure&#xff08;基础设备&#xff09;隔离开来 ApplicationDocker EngineInfrastructure(physical/virtual) 1.1Docker Engine组成 后台…

【前端素材】推荐优质后台管理系统GramOs平台模板(附源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;它通常作为一个独立的后台界面存在&#xff0c;供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能&#xff1a; 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…

Imagewheel私人图床搭建结合内网穿透实现无公网IP远程访问教程

文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…