[C++]C/C++内存管理——喵喵要吃C嘎嘎5

2024-03-26 08:44
文章标签 c++ 内存 管理 嘎嘎

本文主要是介绍[C++]C/C++内存管理——喵喵要吃C嘎嘎5,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

希望你开心,希望你健康,希望你幸福,希望你点赞!

最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!!

喵喵喵,你对我真的很重要!

目录

前言

C/C++内存分布

C++内存管理方式

new/delete操作内置类型

new和delete操作自定义类型

operator new与operator delete函数

operator new与operator delete函数(重点)

重载operator new与operator delete(了解)

总结


前言

人生苦短,看开一点;人生冷暖,经历一点;人生功名,看淡一点;人生情谊,温暖一点;祝福送上,快乐一点。


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. 又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
  3. 用于程序运行时动态内存分配,堆是可以上增长的。
  4. 数据段--存储全局数据和静态数据。
  5. 代码段--可执行的代码/只读常量。

C++内存管理方式

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

new/delete操作内置类型

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

注意:申请和释放单个元素的空间,使用newdelete操作符,申请和释放连续的空间,使用

new[]delete[],注意:匹配起来使用。


newdelete操作自定义类型

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)); // C int* 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不会


operator newoperator delete函数

operator newoperator delete函数(重点)

newdelete是用户进行动态内存申请和释放的操作符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)
{
// 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与operator delete(了解)

字节
void* operator new(size_t size, const char* fileName, const char* funcName, size_t lineNo)
{
void* p = ::operator new(size);
cout << fileName << "-" << funcName << "-" << lineNo << "-" << p << "-"
<< size << endl; return p;
}// 重载operator delete,在释放空间时:打印再那个文件、哪个函数、第多少行释放
void operator delete(void* p, const char* fileName, const char* funcName, size_t lineNo)
{
cout << fileName << "-" << funcName << "-" << lineNo << "-" << p << endl;
::operator delete(p);
}int main()
{
// 对重载的operator new 和 operator delete进行调用 int* p = new(  FILE  ,   FUNCTION  ,   LINE  ) int;
operator delete(p,   FILE  ,   FUNCTION  ,   LINE  ); return 0;
}// 上述调用显然太麻烦了,可以使用宏对调用进行简化
// 只有在Debug方式下,才调用用户重载的 operator new 和 operator delete #ifdef _DEBUG
#define new new(  FILE  ,   FUNCTION  ,   LINE  )
#define delete(p) operator delete(p,   FILE  ,   FUNCTION  ,   LINE  ) #endifint main()
{
int* p = new int; delete(p); return 0;
}

注意:一般情况下不需要对 operator new operator delete进行重载,除非在申请和释放空间时候有某些特殊的需求。比如:在使用newdelete申请和释放空间时,打印一些日志信息,可以简单帮助用户来检测是否存在内存泄漏。


总结

C/C++内存分bu

C++内存管理方式

new/delete操作内置类型

new和delete操作自定义类型

operator new与operator delete函数

operator new与operator delete函数(重点)

重载operator new与operator delete(了解)


希望你开心,希望你健康,希望你幸福,希望你点赞!

最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!!

喵喵喵,你对我真的很重要!

这篇关于[C++]C/C++内存管理——喵喵要吃C嘎嘎5的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/847922

相关文章

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

SpringBoot使用minio进行文件管理的流程步骤

《SpringBoot使用minio进行文件管理的流程步骤》MinIO是一个高性能的对象存储系统,兼容AmazonS3API,该软件设计用于处理非结构化数据,如图片、视频、日志文件以及备份数据等,本文... 目录一、拉取minio镜像二、创建配置文件和上传文件的目录三、启动容器四、浏览器登录 minio五、

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

IDEA中的Kafka管理神器详解

《IDEA中的Kafka管理神器详解》这款基于IDEA插件实现的Kafka管理工具,能够在本地IDE环境中直接运行,简化了设置流程,为开发者提供了更加紧密集成、高效且直观的Kafka操作体验... 目录免安装:IDEA中的Kafka管理神器!简介安装必要的插件创建 Kafka 连接第一步:创建连接第二步:选

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数