动态内存管理题目讲解

news2025/1/18 8:45:53

前言:
上一期我们讲述了有关动态内存管理的知识点,这期我们通过几个经典的笔试题来进行深入的了解以及对知识点的巩固

目录

  • 第一题
  • 第二题
  • 第三题
  • 第四套

第一题

试题如下:

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

运行结果如下:
在这里插入图片描述
通过上述我们可以发现程序已经崩了。
解答:

上述代码主要存在以下错误。

  1. 这里传入的是一级指针,没有对str中存放的地址NULL进行改变,所以后面执行strcmp的内容会让程序崩溃。
    动态申请内存有可能失败,所以应该增加判断。
  2. 动态创建的内存没释放。

改正方法:
方法一:如果需要改变str,改变变量用一级指针,改变指针用二级指针,所以我们可以使用二级指针对其进行操作,如下:

void GetMemory(char** p)
{
	*p = (char*)malloc(100);
	if (NULL == p)
	return 1;
}

void Test(void)
{
	char* str = NULL;
	GetMemory(&str);
	strcpy(str, "hello world");
	printf(str);
	//释放
	free(str);
	str = NULL;
}

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

方法二:还有一种方法是,将动态申请的内存以返回值的形式传出。

char* GetMemory(char* p)
{
	p = (char*)malloc(100);
	return p;
}

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

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

第二题

试题如下:

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

void Test(void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}

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

运行结果如下:
在这里插入图片描述
通过结果不难发现程序运行错误。
解答:

这是返回栈空间地址问题,p的生命周期在GetMemory函数执行完了就被销毁了,str指向的是个野指针, GetMemory 并不能传递动态内存,Test 函数中的str 一直都是 NULL。strcpy(str, “hello world”);将使程序崩溃。
当然没有内存释放也是它存在的一个问题

第三题

试题如下:

void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}

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

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

运行结果如下
在这里插入图片描述
上述我们可以发现是正常,那么真的是这样吗?
解答:
其实这题存在一个很简单的申请未释放的问题,导致内存泄漏。

改正:

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

第四套

试题如下:

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

运行结果如下:
在这里插入图片描述
我们发现这跟第三题一样,并没有出现报错,那么它是正确的吗?答案当然是否定的。
解答:

执行 char *str = (char *) malloc(100); 后未进行内存是否申请成功的判断;
另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上: str = NULL;

改正:

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

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

以上就是关于动态内存管理的几个经典的试题,大家通过练习我相信对我们的知识点的掌握肯定更加牢固!

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

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

相关文章

1.H3CNE-计算机网络概述

计算机网络概述计算机网络定义一组自治计算机互联的集合计算机网络基本功能资源共享综合信息服务分布式处理与负载均衡计算机网络的类型局域网LAN(Local Area Network) 由用户自行建设,使用私有地址组建的网络城域网MAN(Metropolitan Area Network)由运营…

为什么职场第一开发语言会是SQL?看完这些你就瞬间明白了

看到一个有趣的比喻,用来说明SQL与Excel的差别是什么。 如果把SQL比作火车,把Excel更比作卡车。 卡车灵活自由,高速或乡村小道想去哪就去哪,但即便每天不停歇卡车的运载量也不大,而且容易出交通事故。 火车运载量大…

windows下软件安装:miniconda下安装R4.1.3并将其添加到 Jupyter notebook 中

0. 说明: 本来是想在windows中用conda安装R,然后再下载安装RStudio并对其进行配置使之可以用conda环境中的R,但是经过尝试以及网络上查找相关文档发现,原版RStudio不支持使用conda环境中的R(可能Anaconda中自带的RStu…

Visual studio C++桌面应用程序添加外部文件引用

C桌面应用程序添加外部文件引用 前言 之前对C的开发接触很少,本章节记录一下Visual studio开发C桌面应用程序是如何引入外部文件 ★提高阅读体验★ 👉 ♠一级标题 👈 👉 ♥二级标题 👈 👉 ♥ 三级标…

Apache Spark 机器学习 基本统计 1

1 基本概念 相关性,是指两个变量或者两个系列变量的关联程度,也就是,其中一方变量的变化会影响另外一方变量的变化。 相关性分为三种关系,正相关、负相关以及不相关。 正相关,从单调递增的角度看,其中一…

Netty基础入门——文件编程、网络编程【2】

Netty基础入门——文件编程、网络编程【2】 基础入门【1】 1 文件编程 1.1 channel 两个channel传输数据 transferTo方法一次性最多传输2G大小的文件,如果超出会丢弃 public static void main(String[] args) {try (FileChannel from new FileInputStream(&quo…

APM系统是什么?有什么用处?

自SpringCloud问世以来,微服务以席卷之势风靡全球,企业架构都在从传统SOA向微服务转型。然而微服务这把双刃剑在带来各种优势的同时,也给运维、性能监控、错误的排查带来的极大的困难。在大型项目中,服务架构会包含数十乃至上百个…

分布式助力光伏太阳能规模化发展解决方案

行业背景 光伏太阳能作为一种清洁环保的能源,得到各种开发利用,光伏太阳能电池板是其中的重点研究对象,其质量是影响太阳能电池发电效率的主要因素,所以对电池板表面质量的检测是生产中一个重要环节。随着工业的发展,太阳能电池板…

198:vue+openlayers 解决drawend后不能获取当前feature的方法

第198个 点击查看专栏目录 本示例的目的是介绍如何在vue+openlayers项目中绘制矩形,drawend触发事件,要获取到当前绘制的feature的信息。drawend触发的时刻,add feature to the source or collection 这个变化还没有发生,所以用source.getFeatures()是获取不到最新数据的。可…

OpenStack 认证Api

在调用OpenStack的Api或者其它组建的Api时都需要进行 OpenStack 认证,在这里记录一下如何调用OpenStack 认证接口或者token 和给其它接口增加token的方式一. 调用OpenStack auth接口接口地址:http://ip:5000/v3/auth/tokens参数:{"auth&…

特色风情小镇行业发展动态及市场需求前景分析

2023-2029年中国特色风情小镇行业发展动态及市场需求前景报告报告编号:1691653免费目录下载:http://www.cninfo360.com/yjbg/qthy/qt/20230110/1691653.html本报告著作权归博研咨询所有,未经书面许可,任何组织和个人不得以任何形式…

结构体内存对齐与结构体位段:学习笔记8

目录 一.结构体基础知识 1. 结构体的特殊声明 2. 结构的自引用 3.结构体变量的定义和初始化 二.结构体内存对齐 1.关键概念: 2.计算示例 3.嵌套结构体的内存计算 4.结构体内存对齐的意义 5.定义结构体时的注意事项 6.修改默认对齐数 附:关…

【PWA学习】5. 使用 Notification API 来进行消息提醒

引言 在上一节, 介绍了如何使用 Push API 进行服务端消息推送。提到 Push 就不得不说与其联系紧密的另一个 API——Notification API。它让我们可以在“网站外”显示消息提示: 消息推送示例即使当你切换到其他 Tab,也可以通过提醒交互来快速让用户回到你…

webviz安装,docker安装可正常使用与Foxglove Studio

Foxglove Studio Foxglove Studio与webviz使用起来非常类似 去可以直接使用web也可以下载安装包 Foxglove Studio不提供源码 安装包下载地

linux cgroup、kubernetes limit

linux cgroup、kubernetes limit 1.cgroups 简介 cgroups,其名称源自控制组群(control groups)的缩写,是内核的一个特性,用于限制、记录和隔离一组进程的资源使用(CPU、内存、磁盘 I/O、网络等&#xff0…

JSP——分页查询

✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏:JAVA开发者…

Homekit智能家居DIY产品一智能面板开关

触摸开关,即通过触摸方式控制的墙壁开关,其感官场景如同我们的触屏手机,只需手指轻轻一点即可达到控制电器的目的,随着人们生活品质的提高,触摸开关将逐渐将换代传统机械按键开关。 触摸开关控制原理 触摸开关我们把…

【广度优先搜索遍历 BFS】单词接龙

一、题目描述 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk&#xff1a; - 每一对相邻的单词只差一个字母。 - 对于 1 < i < k 时&#xff0c;每个 si 都在 wordList 中。注意…

全面详解Java垃圾回收器

一&#xff1a;什么是垃圾回收 Java 方法栈、本地方法栈随着方法结束或者线程结束&#xff0c;堆中的对象是用完&#xff0c;都会进行回收内存&#xff0c;所以这些区域的内存分配和回收都具备确定性&#xff0c;不需要额外考虑回收的问题。而堆和方法区存储的对象可能只有在运…

Ad5761r GD32 STM32 驱动设计

MCU采用GD32,GD32基本上和STM32一样,针对ad5761r的时序操作是完全相同的.软、硬件设计已经再产品设计中实际使用。本文章提供参考硬件设计&#xff0c;以及对应的源代码&#xff0c;具体可以作为实际项目的参考设计AD5761R是一款单通道、16位串行输入、电压输出DAC。该器件采用…