C++内存分布知识点复习

C++内存分布(只是用来自己复习,如果侵权了请联系,马上删除)

看看自己是否了解

#define  _CRT_SECURE_NO_WARNINGS
#include<malloc.h>
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在哪里?____
    在这里插入图片描述
    *1. 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的。

  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口
    创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)

  3. 堆用于程序运行时动态内存分配,堆是可以上增长的。

  4. 数据段–存储全局数据和静态数据。

  5. 代码段–可执行的代码/只读常量。

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

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);


}
  1. malloc/calloc/realloc的区别?
    1 ,malloc 是申请空间,需要输入一个参数(输入的参数是你想开辟空间的大小),返回的类型是void*
    2 ,calloc也是申请一个空间,需要输入的参数是有两个(第一个参数(是指你需要开辟的个数),第二个参数是类型(你需要开辟数据的类型))。它会将所分配的内存块的每个字节初始化为零。
    3 relloc是对之前开辟的空间进行重新申请,也需要传入两个参数(第一个参数是地址的指针,第二个参数是你要重新分配的内存的大小)。

2 这里需要free(p2)吗?
是的,使用realloc重新分配内存后,原始内存块会被释放。这意味着你不需要再显式地释放原始内存块,因为realloc会负责这个任务。
然而,需要注意的是,如果realloc失败(返回NULL),原始内存块仍然会被保留。在这种情况下,你需要确保不再需要原始内存块,并且释放它以避免内存泄漏。

C++内存管理方式

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

int main()
{
	int* ptr = new int;
	int* ptr5 = new int(10);
	int* ptr6 = new int[3];
	delete ptr;
	delete ptr5;
	delete[] ptr6;
	return 0;
}

在这里插入图片描述

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

new和delete操作自定义类型

#include<iostream>
using namespace std;
class A
{
public:
	A(int a=0)
		:_a(a)
	{
		cout << "A(int a=0)" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}

private:
	int _a;
};

int main()
{
	A* a = new A();
	A b;
	A c;
	return 0;
}

在这里插入图片描述
这里最后一个析构函数执行的时候,程序就会结束,导致最后一个没有打印,但是析构函数确实是执行了三次。
注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。

/*
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)
new和delete的实现原理

如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:
1 new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

5.2 自定义类型
new的原理

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

定位new表达式(placement-new)

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式:
new (place_address) type或者new (place_address) type(initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表

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;
}

malloc/free和new/delete的区别

malloc/free 是函数,new和delete是操作符

malloc申请的空间不会初始化,new可以初始化

malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可

malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常

申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

内存泄漏

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

优秀人才必须具备的5个基本素质?

哈喽&#xff0c;大家好啊&#xff0c;我是雷工&#xff01; 张一鸣曾经在其微博上说过这么一句话&#xff1a; 选择越高级影响越大的人才&#xff0c;越要看一些基本素质。 那么优秀人才都具备哪些较好的基本素质呢&#xff1f; 或者说要具备哪些基本素质才有望成为高级人才&a…

[文生音乐]Suno AI:一句话,创作自己的音乐,全民创作人时代!

前言&#xff1a; 今年继AI生成文字&#xff08;Claude3&#xff09;、AI生成图片&#xff08;Midjourney&#xff09;、AI生成视频&#xff08;Sora&#xff09;之后&#xff0c;国外的AI公司又推出了一个劲爆的工具&#xff1a;Suno AI&#xff0c;通过一段简短的描述&#…

4G/5G视频记录仪_联发科MTK6765平台智能记录仪方案

视频记录仪主板采用了联发科MT6765芯片&#xff0c;该芯片采用12nm FinFET制程工艺&#xff0c;8*Cortex-A53架构&#xff0c;搭载安卓11.0/13.0系统&#xff0c;主频最高达2.3GHz&#xff0c;待机功耗可低至5ma&#xff0c;并具有快速数据传输能力。配备了2.4英寸高清触摸显示…

解决 cv2.imread读取带中文路径图片问题

http://t.csdnimg.cn/i8CXn 1.问题&#xff1a; # 中草药数据集样本可视化展示 import cv2 import matplotlib.pyplot as plt %matplotlib inline plt.title("heshouwu") plt.imshow(cv2.imread(r"D:\home\aistudio\data1\archive\train\何首乌\heshouwu_0001.…

huggingface的transformers训练bert

目录 理论 实践 理论 https://arxiv.org/abs/1810.04805 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是一种自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;由Google在2018年提出。它是基于Transformer模型的预训练方法…

机器学习(一)

经典定义: 利用经验改善系统自身的性能。 经典的机器学习过程: 基本术语: 数据集:训练集、测试集 示例、样例、样本 属性、特征:属性值 属性空间、样本空间、输入空间 特征向量 标记空间、输出空间 归纳偏好(偏置): 任何一个有效的机器学习算法必有其偏好 学习算法的…

ConcurrentHashMap 为什么是线程安全的?

1、典型回答 ConcurrentHashMap 在不同JDK 版本中&#xff0c;保证线程安全的手段是不同的&#xff0c;它主要分为以下两种情况&#xff1a; JDK 1.7 之前(包含JDK 1.7)&#xff0c;ConcurrentHashMap 主要是通过分段锁 (Segment Lock) 来保证线程安全的。而在JDK 1.8 之后(包…

C语言----strcpy和strcat的使用和模拟实现

一&#xff0c;strcpy()函数 strcpy() 函数是 C语言中一个非常重要的字符串处理函数&#xff0c;其功能是将一个字符串复制到另一个字符串中。该函数原型如下&#xff1a; char*strcpy(char*dest,const char*src) 其中&#xff0c;dest 表示目标字符串&#xff0c;即将被复制到…

iOS开发之SwiftUI

iOS开发之SwiftUI 在iOS开发中SwiftUI与Objective-C和Swift不同&#xff0c;它采用了声明式语法&#xff0c;相对而言SwiftUI声明式语法简化了界面开发过程&#xff0c;减少了代码量。 由于SwiftUI是Apple推出的界面开发框架&#xff0c;从iOS13开始引入&#xff0c;Apple使用…

时间戳的转换-unix时间戳转换为utc时间(python实现)

import datetimetimestamp = 1711358882# 将时间戳转换为UTC时间 utc_time = datetime.datetime.utcfromtimestamp(timestamp)# 格式化并输出时间 formatted_time = utc_time.strftime(%Y-%m-%d %H:%M:%S) print(formatted_time)同样:UTC如何转换为unix时间戳 from datetime …

P6技巧:对计划执行纠偏措施

前言 对施工计划的滞后原因分析&#xff0c;通常采取由大到小、由高到低的方法。即首先查看总体进度偏差&#xff0c;再分析其偏差主要来源于哪部分。 项目进度评估与偏差控制 项目实施过程中&#xff0c;项目控制人员应对进度实施情况进行跟踪、采集数据&#xff0c;并根据…

OC高级编程 第3章:Grand Central Dispatch

3.1 Grand Central Dispatch (GCD)概要 3.1.1什么是GCD Grand Central Dispatch&#xff08;GCD&#xff09;是异步执行任务的技术之一。一般将应用中记述线程管理用的代码在系统级中实现。开发者只要定义想执行的任务并追加到Dispatch Queue中&#xff0c;GCD就能生成必要的…

5 IOC/DI注解开发

文章目录 3&#xff0c;IOC/DI注解开发3.1 环境准备3.2 注解开发定义bean步骤1:删除原XML配置步骤2:Dao上添加注解步骤3:配置Spring的注解包扫描步骤4&#xff1a;运行程序步骤5:Service上添加注解步骤6:运行程序知识点1:Component等 3.2 纯注解开发模式3.2.1 思路分析3.2.2 实…

Linux下对线程的认识+生产消费者模型+信号量

线程的概念 线程是进程内部中更加轻量化的一种执行流。线程是CPU调度的基本单位&#xff0c;而进程是承担系统资源的实体。就是说一个进程中可能会有多个线程&#xff0c;而在Linux内核中并没有真正重新的创建线程并重新进行资源分配&#xff0c;因为我们每个线程指向的资源都是…

mac电脑下安装和启动nginx

一,安装homebrew 必须安装了homebrew&#xff0c;可在终端输入命令brew -v查看是否已经安装,没安装的话安装一下: 如果未安装先安装&#xff08;网上很多文章&#xff09; 二,查看nginx是否存在 使用命令:brew search nginx查看nginx是否存在: 不存在的话,就使用brew inst…

Java螺旋折线

题目描述 如图所示的螺旋折线经过平面上所有整点恰好一次。 对于整点 (X,Y)&#xff0c;我们定义它到原点的距离dis(X,Y) 是从原点到 (X,Y) 的螺旋折线段的长度。 例如 dis(0,1)3&#xff0c;dis(−2,−1)9。 给出整点坐标 (X,Y)&#xff0c;你能计算出 dis(X,Y) 吗&#xf…

HCIA实验

实验目的&#xff1a; 1、R6为ISP&#xff0c;接口IP地址均为公有地址&#xff0c;该设备只能配置IP地址&#xff0c;之后不能再对其进行任何配置&#xff1b; 2、R1-R5为局域网&#xff0c;私有IP地址192.168.1.0/24&#xff0c;请合理分配&#xff1b; 3、R1、R2、R4&#x…

如何着手写一个自己的网站管理客户端

WebHole 项目地址 https://gitee.com/yiyefangzhou24/web-hole 是什么&#xff1f;能干什么&#xff1f; WebHole是一款网站管理软件&#xff0c;类似但不同于菜刀、冰蝎、蚁剑&#xff0c;能通过C/S的工作模式&#xff0c;方便的管理服务器的文件、数据库&#xff0c;并执…

自定义类型(2)

1联合体 1.1 联合体类型的声明 像结构体⼀样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。 但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所 以联合体也叫&#xff1a;共⽤体。 给联合体其…

基于springboot+vue的流浪动物管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…