C语言动态内存经典笔试题分析

C语言动态内存经典笔试题分析

文章目录

  • C语言动态内存经典笔试题分析
    • 1. 题目一
    • 2. 题目二
    • 3. 题目三
    • 4. 题目四

1. 题目一

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

运行Test函数会有什么结果?

代码运行时会崩溃
上述代码中出现的问题

  1. malloc开辟的空间没有释放,内存泄漏
  2. 代码会崩溃,即使GetMemory函数返回,str依然为NULL
  3. GetMemory函数无法把malloc开辟的100个字节带回来

TIP:上述代码中的printf(str);没有错,与printf(“abcdef”); printf(“%s”,str);一样,都是将数组的首元素地址传给kbd>printf

代码出现的主要问题是GetMemory函数返回,str依然为NULL
在这里插入图片描述
分析:
传给GetMemory函数的只是str中的值,并不是str的地址,使用为传值调用,传值调用形参的改变并不会改变实参,形参只是实参的临时拷贝,所以str中的值不会改变,在使用strcpy时,对NULL指针解引用了,导致程序崩溃

上述代码的修改:

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

2. 题目二

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

运行Test函数会有什么结果?

正常打印hello

分析:
与题目一类似,不过这段代码时将,str地址传给了GetMemory函数,函数形参使用二级指针存放指针的地址,并将开辟好的空间的地址赋值给p,也就是str,代码并没有明显问题,并不会像代码一一样崩溃

只不过这段代码没有释放malloc开辟的空间,会导致内存泄漏

上述代码的修改:

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

3. 题目三

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

运行Test函数会有什么结果?
代码打印的结果是不确定的

分析:
这段代码错就错在返回了局部变量的地址,局部变量的生命周期在出作用域就结束了,也就是在调用完GetMemory函数之后,p就被销毁了,还给了操作系统,在下面用指针接收了局部变量的地址时,这个指针就是野指针,代码打印会出不确定的结果

可以简化下这段代码:

int* test()
{int n = 10;return &n;
}
int main()
{int* ret = test();printf("hello\n");printf("%d", *ret);return 0;
}

打印出的结果为不确定的
分析:
上述代码就是明显返回了局部变量的地址,如果没有 printf(“hello\n”);这段的话,代码虽然能正常运行但是不代表没错,printf(“hello\n”);这段的话破坏了函数的栈帧空间,导致打印的值不确定
在这里插入图片描述
在运行代码的时候,main函数开辟一块空间,再为TestTest函数开辟一快空间,再为TestGetMemort函数开辟一快空间,GetMemort函数中有一个字符数组p,并且返回p的地址,数组名就是首字符地址,调用GetMemort函数结束,GetMemort函数被销毁,还给了操作系统,当在打印数组之前,出现了其他代码,就会破坏函数的栈帧空间,导致打印的值为不确定的

4. 题目四

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

代码运行结果正常打印world
运行结果没错不代表结束没错

分析:
在上述代码中,使用strcpy将“hello”拷贝到str中,然后使用free释放了malloc开辟的空间,空间没了,但是空间的地址还在,str没有置NULL,此时str就是野指针,对野指针进行访问就是非法访问,因为野指针指向的一块不属于它的空间

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html通过CDN引入Vue使用Vuex以及Computed、Watch监听

html通过CDN引入Vue使用Vuex以及Computed、Watch监听 近期遇到个需求,就是需要在.net MVC的项目中,对已有的项目的首页进行优化,也就是写原生html和js。但是咱是一个写前端的,写html还可以,.net的话,开发也…

309. 买卖股票的最佳时机含冷冻期(leetcode) 动态规划思想

文章目录 前言一、题目分析二、算法原理1.状态表示2.状态转移方程3.初始化边界条件4.填表顺序5.返回值是什么 三、代码实现总结 前言 在本文章中,我们将要详细介绍一下Leetcode中买卖股票的最佳时机含冷冻期相关的内容,本题采用动态规划的思想解决 一、…

mybatis多表映射-对多关联

1、建库建表 create database mybatis-example; use mybatis-example; create table t_book (bid varchar(20) primary key,bname varchar(20),stuid varchar(20) ); insert into t_book values(b001,Java,s001); insert into t_book values(b002,Python,s002); insert into …

基于Pytorch框架深度学的垃圾分类智能识别系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 垃圾分类智能识别系统是一种基于深度学习技术的智能系统,用于对垃圾进行分类和识别。它使用Pytorch框架…

php实现个性化域名(短网址)和个性化登录模版的解决方案

在PHP中,个性化域名通常指的是根据用户或业务需求动态生成具有特定规律的子域名。实现个性化域名的方法主要依赖于服务器配置和路由规则。下面是一些基本的步骤和考虑因素,以帮助你了解如何个性化域名,并了解这样做的好处。 如何实现个性化域…

XML学习及应用

介绍XML语法及应用 1.XML基础知识1.1什么是XML语言1.2 XML 和 HTML 之间的差异1.3 XML 用途 2.XML语法2.1基础语法2.2XML元素2.3 XML属性2.4XML命名空间 3.XML验证3.1xml语法验证3.2自定义验证3.2.1 XML DTD3.2.2 XML Schema3.2.3PCDATA和CDATA区别3.2.4 参考 1.XML基础知识 1…

App备案、ios备案Bundle ID查询、公钥信息、SHA-1值

App备案、ios备案Bundle ID查询、公钥信息、SHA-1值 Bundle ID这个就不说了,都知道是啥,主要说公钥信息和SHA-1值的获取 打开钥匙串访问,找到当前需要备案App的dis证书,如下: #####右键点击显示简介 #####可以看…

【Linux】地址空间

本片博客将重点回答三个问题 什么是地址空间? 地址空间是如何设计的? 为什么要有地址空间? 程序地址空间排布图 在32位下,一个进程的地址空间,取值范围是0x0000 0000~ 0xFFFF FFFF 回答三个问题之前我们先来证明地址空…

YOLOv8改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)

一、本文介绍 本文给大家带来的改进机制是Slim-neck提出的Neck部分,Slim-neck是一种设计用于优化卷积神经网络中neck部分的结构。在我们YOLOv8中,neck是连接主干网络(backbone)和头部网络(head)的部分&…

Redis和MySQL双写一致性实用解析

1、背景 先阐明一下Mysql和Redis的关系:Mysql是数据库,用来持久化数据,一定程度上保证数据的可靠性;Redis是用来当缓存,用来提升数据访问的性能。 关于如何保证Mysql和Redis中的数据一致(即缓存一致性问题…

[强网拟态决赛 2023] Crypto

文章目录 Bad_rsaClasslcal Bad_rsa 题目描述: from Crypto.Util.number import *f open(flag.txt,rb) m bytes_to_long(f.readline().strip())p getPrime(512) q getPrime(512) e getPrime(8) n p*q phi (p-1)*(q-1) d inverse(e,phi) leak d & ((1…

洛谷P4071 排列计数

传送门: P4071 [SDOI2016] 排列计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P4071题干: 有多少个1到n的排列a,使得恰好有m个位置满足ai i , 回答T组询问,答案多 10^97取模 数据范围&am…