【进阶C语言】有关动态内存管理的经典笔试题(详细图文讲解)

简介: 【进阶C语言】有关动态内存管理的经典笔试题(详细图文讲解)

题目1:


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


请问运行Test 函数会有什么样的结果?


图片讲解:


p是形参,已离开就会被自动销毁,所以此时p不见了


该代码原理讲解:


1.调用GetMemory函数的时候,str的传参为值传递,p是str的临时拷贝,所以在GetMemory函的内部将动态开辟空间的地址存放在p中的时候,不会影响str.所以GetMemory函数返回之后,str中依然是NULL指针,strcpy函数就会调用失败,原因是对NULL的解引用操作,程序会崩溃。

2.GetMemory函数内容malloc申请的空间没有机会释放,造成了内存泄漏


题目2:


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


请问运行Test 函数会有什么样的结果?


图片讲解:

该代码原理讲解:


返回栈空间地址的问题

GetMemory函数内部创建的数组是临时的,虽然返回了数组的起始地址给了str,但是数组的内存出了GetMemory函数就被回收了,而str依然保存了数组的起始地址,这时如果使用str,str就是野指针。


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


思考一下该代码的结果是什么?


答案是5,跟上面讲的原理一样


图片讲解:


题目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);
}
int main()
{
  Test();
  return 0;
}


请问运行Test 函数会有什么样的结果?


答案是缺少释放

正确更改代码的样子:

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);
}
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);
  }
}
int main()
{
  Test();
  return 0;
}


请问运行Test 函数会有什么样的结果?


答案是str没有被置为空指针

这才是正确的形式

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

如果这份博客对大家有帮助,希望各位给恒川一个免费的点赞👍作为鼓励,并评论收藏一下⭐,谢谢大家!!!

制作不易,如果大家有什么疑问或给恒川的意见,欢迎评论区留言。

相关文章
|
22小时前
|
程序员 编译器 C语言
C语言----动态内存分配(malloc calloc relloc free)超全知识点
C语言----动态内存分配(malloc calloc relloc free)超全知识点
14 6
|
22小时前
|
存储 程序员 编译器
C语言:动态内存管理
C语言:动态内存管理
11 1
|
22小时前
|
存储 编译器 程序员
C语言:数据在内存中的存储
C语言:数据在内存中的存储
13 2
|
23小时前
|
存储 编译器 C语言
C语言:字符函数 & 字符串函数 & 内存函数
C语言:字符函数 & 字符串函数 & 内存函数
15 2
|
22小时前
|
存储 C语言 开发者
【C言专栏】C 语言实现动态内存分配
【4月更文挑战第30天】C语言中的动态内存分配允许程序运行时按需分配内存,提供处理未知数据量的灵活性。这涉及`malloc()`, `calloc()`, `realloc()`, 和 `free()`四个标准库函数。`malloc()`分配指定大小的内存,`calloc()`同时初始化为零,`realloc()`调整内存大小,而`free()`释放内存。开发者需谨慎处理内存泄漏和指针使用,确保程序的稳定性和性能。动态内存分配是C语言中的重要技能,但也需要良好的内存管理实践。
|
22小时前
|
存储 C语言
C语言进阶---------作业复习
C语言进阶---------作业复习
|
23小时前
|
存储 Linux C语言
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)-2
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)
|
22小时前
|
自然语言处理 Linux 编译器
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)-1
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)
|
22小时前
|
存储 编译器 C语言
C语言进阶第十课 --------文件的操作-1
C语言进阶第十课 --------文件的操作
|
23小时前
|
存储 程序员 C语言
C语言进阶第九课 --------动态内存管理-2
C语言进阶第九课 --------动态内存管理

热门文章

最新文章