关于动态内存管理中的常见练习题

news2024/9/22 13:30:44

在这里插入图片描述

文章目录

  • 前言
  • 练习1:
  • 练习2:
  • 练习3:
  • 练习4:

前言

学习完C语言中的动态内存管理,大家开始利用动态内存管理来去开辟空间,经过一顿狂敲代码后,发现了问题,程序要么崩掉,要么运行不起来。小编现在给大家分享动态内存中常见的练习,如有谬误,欢迎指正

请添加图片描述

练习1:

void GetMemory(char* p)
{
	p = (char*)malloc(100);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
}

运⾏Test 函数会有什么样的结果?

敲完代码,运行一下,程序崩掉啦。这里的GetMemory()函数,采用的是值传递,形参是实参的一份临时拷贝。p和str是各自独立的两个指针,GetMemory()函数让p开辟了一个内存空间。但是(重点),p的值最初是在str中拷贝的,拷贝完之后,两个指针没有任何关系。当GetMemory()函数结束后,p的内存就被释放掉了,然后执行srecpy(),此时str仍然是一个空指针,这个程序也就无法被访问。

还有一个问题是,GetMemory()中申请的内存空间没有被释放掉,存在内存泄漏问题。

改进后的代码

void GetMemory(char** p)//形参用二级指针接收,此时p里面存的是str的地址
{
	*p = (char*)malloc(100);//*p得到str,让str指向新开辟的空间
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str);//址传递
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}

int main()
{
	Test();
	return 0;
}

运行结果

hello world

这个问题,在日后会经常遇到,需要留意一下。

练习2:

char* GetMemory(void)
{
	char p[] = "hello world";
	return p;
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}

运⾏会有什么样的结果?
数组p是一个局部变量

在 GetMemory 函数之后,数组 p 的内存空间就被销毁了,还给了操作系统,虽然把这个数组首元素的地址返了回去,但此时再通过地址去访问这一块空间,就成了非法访问。

修改后的代码

char* GetMemory(void)
{
	char* p = "hello world";
	return p;
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}

int main()
{
	Test();
	return 0;
}

运行结果

hello world

练习3:

void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}

运行结果

hello world

这段代码运行后发现是可以的,但是看到了malloc却看不到free,存在内存泄漏问题

修改后的代码

void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
	free(str);
	str = NULL;
}

int main()
{
	Test();
	return 0;
}

练习4:

void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}

运⾏会有什么样的结果?

world

代码也是可以运行的

但是依然有错

因为早在开始,就把str给释放了,这块内存权限给了操作系统

在 free 完后没有把 str 置为空,所以 str 还是指向那块空间,此时的 str 已经变成了一个野指针,后面一些列涉及 str 的操作都属于非法访问。

修改后的代码

void Test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);
	str = NULL;
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}

在这里插入图片描述

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

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

相关文章

字符串的创建(直接赋值与new的区别)- 字符串常量池

文章目录 1.字符串 "hello" 与 new String("hello")的区别2.intern()的使用; 总结 本文开始 1.字符串 “hello” 与 new String(“hello”)的区别 字符串常量池:存储着创建的引用地址的引用 String s1 "hello"; String…

python 之 矩阵相关操作

文章目录 1. **创建矩阵**:2. **矩阵加法**:3. **矩阵乘法**:4. **矩阵转置**:5. **元素级操作**:6. **汇总统计**:7. **逻辑操作**: 理解你的需求,我将为每个功能写一个单独的代码块…

SPI学习笔记:DAC与ACD

一、SPI协议简介 SPI Serial Peripheral Interface,是串行外围设备接口,是一种高速,全双工,同步的通信总线。常规只占用四根线,节约了芯片管脚,PCB的布局省空间。现在越来越多的芯片集成了这种通信协议&a…

python【多线程、单线程、异步编程】三个版本--在爬虫中的应用

并发编程在爬虫中的应用 之前的课程,我们已经为大家介绍了 Python 中的多线程、多进程和异步编程,通过这三种手段,我们可以实现并发或并行编程,这一方面可以加速代码的执行,另一方面也可以带来更好的用户体验。爬虫程…

解读Stata输出的OLS回归结果

Stata是一个广泛用于统计分析和数据管理的软件,以下是一些Stata的基础命令: 输入数据:use + 数据文件路径 显示数据:browse 或 list 或 describe 选择数据:keep 或 drop 或 select 或 exclude 建立变量和赋值:generate 或 replace 汇总数据:summarize 或 tabulate 画图:…

自学SLAM(4)《第二讲:三维物体刚体运动》作业

前言 小编研究生的研究方向是视觉SLAM,目前在自学,本篇文章为初学高翔老师课的第二次作业。 文章目录 前言1.熟悉 Eigen 矩阵运算2.几何运算练习3.旋转的表达4.罗德里格斯公式的证明5.四元数运算性质的验证6.熟悉 C11 1.熟悉 Eigen 矩阵运算 设线性⽅程 …

cordens

1 coredns的用途 CoreDNS 是一个灵活可扩展的 DNS 服务器,可以作为 Kubernetes 集群 DNS,在Kubernetes1.12版本之后成为了默认的DNS服务。 与 Kubernetes 一样,CoreDNS 项目由 CNCF 托管。 coredns在K8S中的用途,主要是用作服务发现&#x…

企业知识库管理软件介绍,打造企业最强大脑!

企业知识经验既是企业稳定可控的基础,也是企业继续长足发展的基石,如何实现组织内外部知识沉淀,让知识在组织内外传播与应用,就成为我们广大企业负责人应该思考的问题了。 企业知识库管理 随着与人工智能技术的融合,知…

arcgis js api 4.x通过TileLayer类加载arcgis server10.2发布的切片服务跨域问题的解决办法

1.错误复现 2.解决办法 2.1去https://github.com/Esri/resource-proxy 网站下载代理配置文件,我下载的是最新的1.1.2版本,这里根据后台服务器配置情况不同有三种配置文件,此次我用到的是DotNet和Java. 2.2 DotNet配置 2.2.1 对proxy文件增加…

第 368 场 LeetCode 周赛题解

A 元素和最小的山形三元组 I 前后缀操作&#xff1a;求出前后缀上的最小值数组&#xff0c;然后枚举 j j j class Solution { public:int minimumSum(vector<int> &nums) {int n nums.size();vector<int> l(n), r(n);//l[i]min{nums[0],...,nums[i]}, r[i]mi…

AirPods Pro的降噪功能让你体验更好,那么如何打开这个功能

本文介绍了如何在AirPods Pro上使用降噪功能&#xff0c;如何关闭它&#xff0c;以及该功能的工作原理。 AirPods Pro和AirPods Max支持降噪。你的设备必须运行iOS 13.2或iPadOS 13.2或更高版本才能使用降噪。 如何在AirPods Pro上打开降噪功能 AirPods Pro凭借其噪音控制功…

leetCode 30.串联所有单词的子串

给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words ["ab","cd","ef"]&#xff0c; 那么 "abcdef&…

如何利用示波器解析I2C数据

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘校园大使&#xff0c;湖南区域的日常实习&#xff0c;任何区域的暑假Linux驱动实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &am…

【5G PHY】5G SS/PBCH块介绍(一)

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

短视频矩阵打造攻略:玩转短视频

短视频矩阵系统是一个智能的短视频创作、发布、管理和分析的平台。该方法能够帮助用户迅速搭建起自身的短视频矩阵&#xff0c;并在多个平台上进行传播与展示&#xff0c;进而提升短视频的营销效率。该短视频矩阵系统具有如下基本功能&#xff1a; 1.短视频制作&#xff1a;为用…

队列的实现方式—Python数据结构(三)

队列 1. 定义 队列是一种常见的数据结构&#xff0c;用于按照先进先出&#xff08;FIFO&#xff09;的原则管理数据项。在Python中&#xff0c;有多种方法可以实现队列&#xff0c;其中最常见的包括使用列表&#xff08;list&#xff09;和使用标准库中的 queue 模块。队列通…

docker运行nginx镜像

今天在这里讲如何在docker上运行nignx镜像&#xff0c;并将配置文件和目录挂载到宿主机上&#xff0c;以实现方便统一的管理配置信息。 首先第一步需要拉取镜像&#xff0c;我们还是拉取最新的镜像&#xff0c;不需要添加tag版本号&#xff0c; docker pull nginx 拉取结束后用…

反射的作用( 越过泛型检查 和 可以使用反射保存所有对象的具体信息 )

1、绕过 编译阶段 为集合添加数据 反射是作用在运行时的技术&#xff0c;此时集合的泛型将不能产生约束了&#xff0c;此时是可以 为集合存入其他任意类型的元素的 。泛型只是在编译阶段可以约束集合只能操作某种数据类型&#xff0c;在 编译成Class文件进入 运行阶段 的时候&a…

Zebec Protocol 薪酬支付工具 WageLink 上线,掀新一轮薪酬支付浪潮

Zebec Protocol 正在从多个方面推动流支付的应用&#xff0c;除了作为一种全新的支付手段来对支付领域进行重塑外&#xff0c;其也在以流支付体系为基础&#xff0c;不断地向薪酬发放领域深度的拓展。 在今年早些时候&#xff0c;Zebec Protocol 通过美国投资机构 Payroll Grow…

【类和对象+this引用】

文章目录 面向对象与面向过程面向对象关注的是对象&#xff0c;用类描述这个对象如何定义类如何更改类名 类的实例化this引用总结 面向对象与面向过程 面向对象就是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。 面向过程好比传统的洗衣服方式&#x…