12.C++内存管理1(C/C++内存分布,C语言动态内存管理)

news2024/11/19 8:19:20

⭐本篇重点:C/C++内存分布,C语言动态内存管理

⭐本篇代码:c++学习/04.c++-动态内存管理 · 橘子真甜/c++-learning-of-yzc - 码云 - 开源中国 (gitee.com)

目录

一. C/C++内存分布(C/C++内存地址空间)

二. C语言动态内存管理

2.1 malloc与free

2.2 calloc

2.3 realloc

三. 易错辨析

3.1 malloc/calloc/realloc的区别?

3.2 malloc的实现原理?

四:下篇内容:C++动态内存管理new和delete


一. C/C++内存分布(C/C++内存地址空间)

在之前一篇Linux的文章中,我们提到了C/C++地址空间:Linux基础4-进程5(程序地址空间详解)-CSDN博客

当时,我们画出的地址空间图如下

当然,实际上在命令行参数的上面还有内核空间

为了更好理解动态内存分布,我们来看一些题目。代码如下

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在哪里?____

globalVar:这个是全局变量,应该位于数据段(全局数据区)

staticGlobalVar:这个是静态数据,位于数据段

staticVar:静态数据位于数据段

localVar:定义的非静态局部变量,位于栈区

num1:非静态局部变量,位于栈区

char2:非静态局部变量,位于栈区

*char2:解引用一个数组名的结果是数组的首个元素,是局部非静态变量,位于栈区

pChar3:非静态局部变量,位于栈区

*pChar3:“abcd”,位于常量区

ptr1:非静态局部变量,位于栈区

*ptr1:结果为malloc开辟的空间,位于堆区

2. 填空题:   sizeof(num1) = ____;  sizeof(char2) = ____;      strlen(char2) = ____;   sizeof(pChar3) = ____;     strlen(pChar3) = ____;   sizeof(ptr1) = ____;

sizeof(num1):使用sizeof计算一个单独的数组名,得到的大小是整个数组的大小:即 10*4 = 40 字节(int占4字节)

sizeof(char2):与上面同理:为 4*1 + 1 = 5 字节(不要忘记了C语言字符串后面有'\0')

strlen(char2):strlen用于计算一个字符串的长度,不包含'\0'(遇到'\0'就会停止)。4*1 = 4 字节

sizeof(pChar3):pChar3是一个指针,在32位操作系统下,指针大小是4字节,64位下指针大小是8字节。8字节

strlen(pChar3):计算字符串长度,遇到'\0'停止。为4字节

sizeof(ptr1):计算指针:为4/8字节

3. sizeof 和 strlen 区别?

sizeof用于计算一个变量所占内存的大小是C/C++提供的一个关键字!

strlen用于计算一个字符串的长度,是C语言提供的一个函数

说明:

非静态局部变量,函数的参数,返回值都位于栈区

用户动态开辟的空间(malloc,new等)位于堆区

代码区:用于存储代码

常量区:用于存放常量,自定义的常量,字符常量等

全局(静态)区:用于存放全局变量和静态变量

二. C语言动态内存管理

学习C++动态内存管理之前,先回顾一个C语言动态内存管理

2.1 malloc与free

malloc用于在堆区申请空间,free用于销毁申请的空间

//头文件
#include <stdlib.h>

//函数原型
void* malloc(size_t size);

//size是申请的空间大小
//申请成功返回一个void*的指针,指向这个空间的起始地址
//我们需要将void*强制转化为我们需要的类型指针

//申请失败返回NULL

用法如下:

#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
	//申请10个int的数组
	int size = 10;//申请的空间大小
	int* arr = (int*)malloc(sizeof(int) * size);
	if (NULL == arr)
		return -1;
	for (int i = 0; i < 10; i++)
	{
		*(arr + i) = i;
	}

	for (int i = 0; i < 10; i++)
	{
		cout << *(arr + i) << " ";
	}
	return 0;
}

运行结果

但是这样是有问题的!

我们在使用malloc申请的空间后,需要使用free去释放这个空间

#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
	//申请10个int的数组
	int size = 10;//申请的空间大小
	int* arr = (int*)malloc(sizeof(int) * size);
	if (NULL == arr)
		return -1;
	for (int i = 0; i < 10; i++)
	{
		*(arr + i) = i;
	}

	for (int i = 0; i < 10; i++)
	{
		cout << *(arr + i) << " ";
	}

	free(arr);//释放空间
	arr = NULL;//防止野指针
	return 0;
}

2.2 calloc

//所需头文件
#include <stdlib.h>

//函数原型
void *calloc(size_t nmemb, size_t size);
//与malloc一样申请空间,但是calloc会将申请的空间都初始化为0

//返回值和malloc一样
//nmemb,申请空间元素的个数
//size,申请空间每一个元素的大小
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
	//申请10个int的数组
	int count = 10;//申请的空间大小
	int* arr1 = (int*)malloc(sizeof(int) * count);
	int* arr2 = (int*)calloc(count, sizeof(int));
	if (arr1 == NULL || arr2 == NULL)
		return -1;

	for (int i = 0; i < count; i++)
	{
		cout << *(arr1 + i) << " ";
	}
	cout << endl;

	for (int i = 0; i < count; i++)
	{
		cout << *(arr2 + i) << " ";
	}

	free(arr1);
	arr1 = NULL;
	free(arr2);
	arr2 = NULL;
	return 0;
}

2.3 realloc

realloc和malloc,calloc有着很大区别,realloc只要用于给申请的空间扩容(当空间满了不够用的时候)

//所需头文件
#include <stdlib.h>

//函数原型
void *realloc(void *ptr, size_t size);

//ptr,需要扩容空间的原指针
//size,扩容后的空间大小

//返回值:扩容后空间的起始地址
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
	//申请10个int的数组
	int count = 10;//申请的空间大小
	int* arr1 = (int*)malloc(sizeof(int) * count);
	if (arr1 == NULL)
		return -1;

	for (int i = 0; i < count; i++)
	{
		*(arr1 + i) = i;
	}
	count = 20;//不够了,要扩容

	int* newarr = (int*)realloc(arr1, sizeof(int) * count);
	if (newarr == NULL)
		return -1;
	arr1 = newarr;
	for (int i = 0; i < count; i++)
	{
		*(arr1 + i) = i * 10;
	}
	for (int i = 0; i < count; i++)
	{
		cout << *(arr1 + i) << " ";
	}
	free(arr1);
	arr1 = NULL;
	return 0;
}

运行结果:

三. 易错辨析

3.1 malloc/calloc/realloc的区别?

见 2.1  2.2  2.3

3.2 malloc的实现原理?

可以看这个视频:malloc实现原理

四:下篇内容:C++动态内存管理new和delete

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

游戏引擎学习第15天

视频参考:https://www.bilibili.com/video/BV1mbUBY7E24 关于游戏中文件输入输出&#xff08;IO&#xff09;操作的讨论。主要分为两类&#xff1a; 只读资产的加载 这部分主要涉及游戏中用于展示和运行的只读资源&#xff0c;例如音乐、音效、美术资源&#xff08;如 3D 模型和…

JavaWeb——JS、Vue

目录 1.JavaScript a.概述 b.引入方式 c.JS的基础语法 d.JS函数 e.JS对象 f.JS事件监听 2.Vue a.概述 b.Vue常用指令 d.生命周期 1.JavaScript a.概述 JavaScript是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互。JavaScript和…

HarmonyOs鸿蒙开发实战(16)=>沉浸式效果第一种方案一窗口全屏布局方案

1.沉浸式效果的目的 开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感&#xff0c;从而使用户获得最佳的UI体验。 2.窗口全屏布局方案介绍 调整布局系统为全屏布局&#xff0c;界面元素延伸到状态栏和导航条区域实现沉…

spi 回环

///tx 极性0 &#xff08;sclk信号线空闲时为低电平&#xff09; /// 相位0 (在sclk信号线第一个跳变沿进行采样) timescale 1ns / 1ps//两个从机 8d01 8d02 module top(input clk ,input rst_n,input [7:0] addr ,input …

CF862B Mahmoud and Ehab and the bipartiteness(二分图的性质)

思路&#xff1a;一个二分图是由两个集合组成的&#xff0c;同一个集合中的节点间不能连边&#xff0c;所以一个二分图最多有cnt[1]*cnt[2]条边&#xff0c;题目给出一个树的n-1条边&#xff0c;要我们添加最多的边数使他成为二分图&#xff0c;添加的边数就是cnt[1]*cnt[2]-n1…

docker:基于Dockerfile镜像制作完整案例

目录 摘要目录结构介绍起始目录package目录target目录sh目录init.sh脚本start.sh脚本stop.sh脚本restart.sh脚本 config目录 步骤1、编写dockerfilescript.sh脚本 2、构件镜像查看镜像 3、保存镜像到本地服务器4、复制镜像文件到指定目录&#xff0c;并执行init.sh脚本5、查看挂…

Redis自学之路—基础数据结构具体方法解析(五)

目录 简介 数据结果具体方法解析 字符串(String) 操作命令 set设置值 setex setnx get获取值 del删除key mset批量设置值 incr数字运算 append追加指令 strlen字符串长度 getset设置并返回原值 setrange设置指定位置的字符 getrange截取字符串 命令的时间复杂…

通过华为鲲鹏认证发行上市的集成平台产品推荐

华为鲲鹏认证是技术实力与品质的权威象征&#xff0c;代表着产品达到了高标准的要求。从技术层面看&#xff0c;认证确保产品与华为鲲鹏架构深度融合&#xff0c;能充分释放鲲鹏芯片的高性能、低功耗优势&#xff0c;为集成平台的高效运行提供强大动力。在安全方面&#xff0c;…

使用 AMD GPU 实现 Segment Anything

Segment Anything with AMD GPUs — ROCm Blogs 作者&#xff1a; Sean Song 发布日期&#xff1a;2024年6月4日 介绍 分割任务——识别图像中哪些像素属于某对象——是计算机视觉中的一个基础任务&#xff0c;应用广泛&#xff0c;从科学图像分析到照片编辑。Segment Anyth…

Spring Cloud Stream实现数据流处理

1.什么是Spring Cloud Stream&#xff1f; 我看很多回答都是“为了屏蔽消息队列的差异&#xff0c;使我们在使用消息队列的时候能够用统一的一套API&#xff0c;无需关心具体的消息队列实现”。 这样理解是有些不全面的&#xff0c;Spring Cloud Stream的核心是Stream&#xf…

无人机飞手入门指南

无人机飞手入门指南旨在为初学者提供一份全面的学习路径和实践建议&#xff0c;帮助新手快速掌握无人机飞行技能并了解相关法规知识。以下是一份详细的入门指南&#xff1a; 一、了解无人机基础知识 1. 无人机构造&#xff1a;了解无人机的组成部分&#xff0c;如机身、螺旋桨…

使用Mac下载MySQL修改密码

Mac下载MySQL MySQL官网链接MySQL​​​​​​ 当进入到官网后下滑到community社区&#xff0c;进行下载 然后选择community sever下载 这里就是要下载的界面&#xff0c;如果需要下载之前版本的话可以点击archives&#xff0c; 可能会因为这是外网原因&#xff0c;有时候下…

两大新兴开发语言大比拼:Move PK Rust

了解 Move 和 Rust 的差异有助于开发者根据项目的具体需求选择最合适的语言。选择不恰当的语言可能会导致项目后期出现技术债务。不同语言有其独特的优势。了解 Move 和 Rust 的差异可以帮助开发者拓展技术视野&#xff0c;发现不同语言在不同领域的应用潜力。 咱们直奔主题&a…

three.js 对 模型使用 视频进行贴图修改材质

three.js 对 模型使用 视频进行贴图修改材质 https://threehub.cn/#/codeMirror?navigationThreeJS&classifyapplication&idvideoModel import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls.js import { GLTFLoad…

【论文分享】利用多源大数据衡量街道步行环境的老年友好性:以中国上海为例

本次给大家带来一篇SCI论文的全文翻译&#xff01;该论文考虑了绿化程度、可步行性、安全性、形象性、封闭性和复杂性这六个指标&#xff0c;提出了一种基于多源地理空间大数据的新型定量评价模型&#xff0c;用于从老年人和专家的角度评估街道步行环境的老年友好程度&#xff…

计算机网络安全 —— 对称加密算法 DES (一)

一、对称加密算法概念# ​ 我们通过计算机网络传输数据时&#xff0c;如果无法防止他人窃听&#xff0c; 可以利用密码学技术将发送的数据变换成对任何不知道如何做逆变换的人都不可理解的形式&#xff0c; 从而保证了数据的机密性。这种变换被称为加密&#xff08; encryptio…

6.C操作符详解,深入探索操作符与字符串处理

C操作符详解&#xff0c;深入探索操作符与字符串处理 C语言往期系列文章目录 往期回顾&#xff1a; C语言是什么&#xff1f;编程界的‘常青树’&#xff0c;它的辉煌你不可不知VS 2022 社区版C语言的安装教程&#xff0c;不要再卡在下载0B/s啦C语言入门&#xff1a;解锁基础…

微信小程序 最新获取用户头像以及用户名

一.在小程序改版为了安全起见 使用用户填写来获取头像以及用户名 二.代码实现 <view class"login_box"><!-- 头像 --><view class"avator_box"><button wx:if"{{ !userInfo.avatarUrl }}" class"avatorbtn" op…

Uni-APP+Vue3+鸿蒙 开发菜鸟流程

参考文档 文档中心 运行和发行 | uni-app官网 AppGallery Connect DCloud开发者中心 环境要求 Vue3jdk 17 Java Downloads | Oracle 中国 【鸿蒙开发工具内置jdk17&#xff0c;本地不使用17会报jdk版本不一致问题】 开发工具 HBuilderDevEco Studio【目前只下载这一个就…

【Android、IOS、Flutter、鸿蒙、ReactNative 】屏幕适配

Android Java 屏幕适配 参考 今日头条适配依赖配置 添加设计屏幕尺寸 设置字体大小 通过切换不同屏幕尺寸查看字体大小 设置文本宽高 通过切换不同屏幕尺寸查看文本宽高 Android Compose 屏幕适配 <