前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C语言进阶篇】动态内存常考笔试题

【C语言进阶篇】动态内存常考笔试题

作者头像
鸽芷咕
发布2023-12-25 14:43:14
830
发布2023-12-25 14:43:14
举报
文章被收录于专栏:C++干货基地C++干货基地
在这里插入图片描述
在这里插入图片描述

🎬 鸽芷咕个人主页 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》

⛺️生活的理想,就是为了理想的生活!


文章目录
  • 📋 前言
  • 💬 C/C++程序的内存开辟
    • 💭 内存布局图:
  • 💬几个经典的笔试题:
    • 💭 题目1:
      • 请问运行Test 函数会有什么样的结果?
    • 💭 题目2:
      • 请问运行Test 函数会有什么样的结果?
    • 💭 题目3:
      • 请问运行Test 函数会有什么样的结果?
      • ✅ 代码改进
    • 💭 题目4:
      • 请问运行Test 函数会有什么样的结果?
      • ✅ 代码改进
  • 全篇总结

📋 前言

🌈hello!各位宝子们大家好啊,关于动态内存管理和 位段 等知识我们在前面一篇已经详细介绍了? ⛳️今天就来看看这些经典的笔试题你会做吗?而这需要一些基本的C/C++程序内存分配的几个区域这些知识,今天就给大家一起讲一讲! 📚本期文章收录在《C语言进阶篇》,大家有兴趣可以看看呐! ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

🔥 注:本笔试题出自《高质量的C/C++编程》林锐博士这本书 《高质量的C/C++编程》《动态内存管理》《位段 联合 枚举》

💬 C/C++程序的内存开辟

  ⛳️大家在学习C语言的过程中不知道思没思考过这个问题!我们每次创建的变量或者开辟的动态内存空间究竟是在内存中的那个位置开辟的呢?今天就给大家讲讲!

📑 C/C++程序内存分配的几个区域:

  1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结 束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是 分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返 回地址等。
  2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分 配方式类似于链表。
  3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
  4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。

这些就是我们C/C++在运行中的大致内存区域不知道现在清楚了嘛?那么我们在来看这幅图相信大家就明白了

💭 内存布局图:

在这里插入图片描述
在这里插入图片描述

用通俗易懂的话来描述就是:

  1. 栈区(stack):存放的是我们平常创建的变量 形参 等 临时变量!
  2. 堆区(heap):目前我们学的动态内存分配 都是在堆区开辟的!
  3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
  4. 代码段可执行代码 和 只读 常量

💬几个经典的笔试题:

  ⛳️好了这些C/C++的内存分布我们懂了下面的经典笔试题就可以做一做了看一下你是否真的理解了

💭 题目1:

代码语言:javascript
复制
void GetMemory(char *p)
{
 p = (char *)malloc(100);
}
void Test(void)
{
 char *str = NULL;
 GetMemory(str);
 strcpy(str, "hello world");
 printf(str);
}

  ⁉️这里我们看的这个程序的意思大概就是,把我们的字符类型的指针变量传给 GetMemory 函数想利用它来为我们开辟空间并返回!

  • 下面我们运行一下看看
请问运行Test 函数会有什么样的结果?
在这里插入图片描述
在这里插入图片描述

我们代码运行了,却是这样的结果!其实这个代码有3个问题

  1. 我们这里传过去的是指针变量 并不是地址 ,所以而p是str的一份临时拷贝改变形参并不会改变实参所以当GetMemory 函数结束时 p 还是NULL空指针
  2. malloc开辟的空间并未释放, GetMemory 函数返回时 p 会销毁。导致内存泄漏
  3. p 开辟的100个字节空间与 str 无关所以,str 还是空指针。
  4. 而我们 strcpy 对空指针解引用,程序肯定会崩溃!
在这里插入图片描述
在这里插入图片描述

💭 题目2:

代码语言:javascript
复制
char *GetMemory(void)
{
 char p[] = "hello world";
 return p;
}
void Test(void)
{
 char *str = NULL;
 str = GetMemory();
 printf(str);
}
请问运行Test 函数会有什么样的结果?
在这里插入图片描述
在这里插入图片描述

我们代码运行了,却是这样的结果!其实这个代码有3个问题

  1. 我们的数组a是在栈空间开辟的,所以当GetMemory函数结束时会 销毁
  2. 虽然我们返回的是 数组 的首地址,但是这个地址是野指针啊
  3. 所以我们在访问这个数组时就会非法访问,导致访问的是一段乱码!
  4. 这个属于返回栈空间地址的问题 在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

💭 题目3:

代码语言:javascript
复制
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 函数会有什么样的结果?
在这里插入图片描述
在这里插入图片描述

我们代码运行了,看上去结果没有问题!其实这个代码也有3个问题

  1. 那就是动态内存申请的空间没有free释放! 这样我们的代码就更加完美了
✅ 代码改进
代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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:

代码语言:javascript
复制
void Test(void)
{
 char *str = (char *) malloc(100);
 strcpy(str, "hello");
 free(str);
 if(str != NULL)
 {
 strcpy(str, "world");
 printf(str);
 }
}
请问运行Test 函数会有什么样的结果?
在这里插入图片描述
在这里插入图片描述

我们代码运行了,看上去结果没有问题!其实这个代码也有3个问题

  1. 那就是动态内存申请的空间提前free释放! str 已经释放了但是我们还使用
  2. 这就会造成问题内存非法访问的问题!所以我们free释放完一定要置为空指针!
✅ 代码改进
代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void Test(void)
{
	char* str = (char*)malloc(100);
	if (str == NULL)
	{
		perror("malloc");
		return 1;
	}
	strcpy(str, "hello");
	free(str);
	str = NULL;
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}

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

全篇总结

✅ 归纳: 好了以上就是关于C/C++的内存分布 和 动态内存管理的笔试题就全部讲解完毕啦! C/C++程序的内存开辟 形参实参问题 返回栈空间地址问题 free为释放 free提前释放 ☁️ 不知道大家今天的这套笔试题看懂多少呢?如果全部看懂了那么恭喜你已经毕业了 看到这里了还不给博主扣个: ⛳️ 点赞☀️收藏 ⭐️ 关注 💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖 拜托拜托这个真的很重要! 你们的点赞就是博主更新最大的动力! 有问题可以评论或者私信呢秒回哦。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 📋 前言
  • 💬 C/C++程序的内存开辟
    • 💭 内存布局图:
    • 💬几个经典的笔试题:
      • 💭 题目1:
        • 请问运行Test 函数会有什么样的结果?
      • 💭 题目2:
        • 请问运行Test 函数会有什么样的结果?
      • 💭 题目3:
        • 请问运行Test 函数会有什么样的结果?
        • ✅ 代码改进
      • 💭 题目4:
        • 请问运行Test 函数会有什么样的结果?
        • ✅ 代码改进
    • 全篇总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档