【学习笔记之我要C】动态内存管理之经典笔试题

简介: 【学习笔记之我要C】动态内存管理之经典笔试题

题目一:

  1. 问题
    请问下面这段代码,运行Test 函数会有什么样的结果?
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;
}


2.代码分析

 str传给GetMemory函数的时候传递的是值,所以GetMemory函数的形参p接收的是一个空指针。GetMemory函数在内部进行动态空间申请,地址存放在p中,并不会影响Test函数中的str。所以str的值依旧是NULL,所以strcpy失败。并且当GetMemory函数运行完之后,形参p销毁,而动态开辟的100个字节内存并没有释放,这样就会导致内存泄露。

3.图解



6a148694f366425c9c5e2e601e0ea522.png

  1. 错误更正
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;
}


题目二


  1. 问题
    请问下面这段代码,运行Test 函数会有什么样的结果?


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


  1. 代码分析
    GetMemory函数内部创建的数组是在栈区上创建的,当函数结束时,这块空间也就销毁了,因此p数组是没有空间的,返回p数组的地址没有实际意义。如果str通过返回的地址去访问内存,就是非法访问。
  2. 图解



10f721b9ac054ddc909a9ca6e9b7b130.png


  1. 错误更正
char* GetMemory(void) {
  char* p = (char*)malloc(15);
  p = "hello world";
  return p;
}
void Test(void) {
  char* str = NULL;
  str = GetMemory();
  printf(str);
}
int main() {
  Test();
  return 0;
}


题目三

  1. 问题
    请问下面这段代码,运行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);
}
int main() {
  Test();
  return 0;
}


  1. 代码分析
    GetMemory函数获取str的地址,然后动态开辟一块空间,把这块空间的地址交给str,最后拷贝“hello”并打印,没有一点问题,但是他没有进行内存释放,会导致内存泄漏。
  2. 图解


968f2498a6b741538e3140684b123c67.png

  1. 错误更正
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;
}


题目四

  1. 问题
    请问下面这段代码,运行Test 函数会有什么样的结果?
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;
}


  1. 代码分析
    这个代码的问题在于没有把置空,会导致野指针,野指针是非常危险的。当free时,动态开辟的空间已经被释放了,只不过str还记得这块空间的地址,在给这块空间赋值属于是非法访问。
  2. 图解



c4f8ddf4c0bb4887a4578b9113a5e4e4.png

  1. 错误更正
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;
}


目录
相关文章
|
11月前
|
程序员 编译器 C语言
一篇博客学会系列(3) —— 对动态内存管理的深度讲解以及经典笔试题的深度解析
一篇博客学会系列(3) —— 对动态内存管理的深度讲解以及经典笔试题的深度解析
113 0
|
11月前
【深入理解计算机系统】int 不是整数 | float 不是实数 | 内存引用错误的例子 | 学习笔记
【深入理解计算机系统】int 不是整数 | float 不是实数 | 内存引用错误的例子 | 学习笔记
69 0
|
11天前
|
编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(上)
动态内存分配与管理详解(附加笔试题分析)
35 1
|
11天前
|
程序员 编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(下)
动态内存分配与管理详解(附加笔试题分析)(下)
25 2
|
2月前
|
存储 程序员 编译器
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
42 0
|
4月前
|
存储 编译器 C语言
【C++】学习笔记——内存管理
【C++】学习笔记——内存管理
50 15
|
4月前
|
存储 C++
C primer plus 学习笔记 第12章 存储类别、链接和内存管理
C primer plus 学习笔记 第12章 存储类别、链接和内存管理
|
4月前
|
程序员 C语言 C++
【C语言基础】:动态内存管理(含经典笔试题分析)-2
【C语言基础】:动态内存管理(含经典笔试题分析)
|
4月前
|
程序员 编译器 C语言
【C语言基础】:动态内存管理(含经典笔试题分析)-1
【C语言基础】:动态内存管理(含经典笔试题分析)
|
4月前
|
程序员 C语言 C++
C语言学习记录——动态内存习题(经典的笔试题)、C/C++中程序内存区域划分
C语言学习记录——动态内存习题(经典的笔试题)、C/C++中程序内存区域划分
125 0