当前位置: 首页 > news >正文

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.lryc.cn/news/257417.html

相关文章:

  • 截断正态分布stats.truncnorm()X.rvs(10000)
  • 第59天:django学习(八)
  • 举例说明自然语言处理(NLP)技术。
  • echarts地图marker自定义图标并添加点击事件
  • C盘瘦身,C盘清理
  • STM32F103
  • Unity使用打成图集的Sprite作为模型贴图使用的问题
  • el-select赋值对象是对象时,出现赋值与展示不一致问题
  • 在 Node-RED 中引入 ECharts 实现数据可视化
  • docker资源限制
  • 探索HarmonyOS_开发软件安装
  • CSS中控制元素水平布局的七个属性
  • YOLOv8改进 | 2023检测头篇 | 利用AFPN改进检测头适配YOLOv8版(全网独家创新)
  • 测试经理的职责是什么?
  • LinuxBasicsForHackers笔记 -- BASH 脚本
  • 定时任务特辑 | Quartz、xxl-job、elastic-job、Cron四个定时任务框架对比,和Spring Boot集成实战
  • 【面试经典150 | 二叉树】对称二叉树
  • 使用Git进行版本控制
  • 专业课145+总分440+东南大学920考研专业基础综合信号与系统数字电路经验分享
  • Leetcode每日一题
  • USB连接器
  • 软件工程之需求分析
  • URL提示不安全
  • JavaBean是什么
  • 202309-2
  • 数字图像处理(实践篇)二十 人脸特征提取
  • Python自动化:selenium常用方法总结
  • 『开源资讯』JimuReport积木报表 v1.6.6 版本发布—免费报表工具
  • 每天五分钟计算机视觉:使用1*1卷积层来改变输入层的通道数量
  • Java (JDK 21) 调用 OpenCV (4.8.0)