“野指针”和大厂经典的动态内存错误笔试题

简介: “野指针”和大厂经典的动态内存错误笔试题

野指针重点总结

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

✔什么情况会出现野指针

1. 指针未初始化

2.局部变量返回的地址

3. 指针越界访问

4. 指针指向的空间释放

当使用动态内存函数申请了内存空间之后,(若str存放起始地址)要将该空间还给操作系统,free(str)释放后,str指向的还是起始位置的地址,这时str是个野指针,因此还要将str置为空指针(str=NULL)

✔如何避免野指针:

①指针初始化

②小心指针越界

③指针指向空间释放即使置NULL

④避免返回局部变量的地址

⑤指针使用之前检查有效性


大厂经典笔试题

✔题目一:

🔺特别注意:

void GetMemory(char* p)
{

    p = (char*)malloc(100);

}

GetMemory(str);

char* p是个局部变量,申请内存后,将内存起始地址赋给p。

str是实际参数,char* p是个形式参数,对p的修改不会影响str

出了函数GetMemory,局部变量p就会销毁,因为局部变量申请的内存没有在出函数GetMemory之前销毁,因此会造成内存泄漏

strcpy(str, "hello world");

因为str是个NULL,使用strcpy函数会报错

printf(str);

str是个地址,printf会根据地址向后打印直到遇见\0

🔸本题答案:内存泄漏,str是NULL指针,运行时程序会崩溃

🔸代码如下:

#include <stdio.h>
//题目一
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;
}

✔题目二:

🔺特别注意:

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

在局部变量中,p是数组首元素的地址,return p返回了该地址。当函数执行完,局部变量运行结束后创建的数组p被系统回收,因此p就是个野指针

char* str = NULL;
   str = GetMemory();

str从空指针到变成一个野指针

🔸本题答案:烫烫烫(随机值)

🔸代码如下:

#include <stdio.h>
//题目二
char* GetMemory(void)
{
  char p[] = "hello world";
  return p;
}
void Test(void)
{
  char* str = NULL;
  str = GetMemory();
  printf(str);
}
int main()
{
  Test();
  return 0;
}

✔题目三:

🔺特别注意:

void GetMemory(char** p, int num)

这里的传参传的是str的地址,因此对p解引用后得到str

忘记释放不再使用的动态开辟的空间会造成内存泄漏

切记: 动态开辟的空间一定要释放,并且正确释放

🔸本题答案:得 hello,但是会造成内存泄漏

🔸代码如下:

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

✔题目四:

🔺特别注意:

free(str);

对malloc申请的空间进行释放后,str虽然还是指向开辟的起始地址,但开辟的内存空间已经被free释放了(不能再使用该空间),所以str是个野指针

🔸本题答案:报错

🔸代码如下:

#include <stdio.h>
//题目四
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;
}

结语

如果对您有帮助的话,

不要忘记点赞+关注哦,蟹蟹

如果对您有帮助的话,

不要忘记点赞+关注哦,蟹蟹

如果对您有帮助的话,

不要忘记点赞+关注哦,蟹蟹

相关文章
|
4月前
|
编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(上)
动态内存分配与管理详解(附加笔试题分析)
95 1
|
6月前
|
存储 C语言
指针和动态内存分配
指针和动态内存分配
120 0
|
3月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
245 13
|
3月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
83 11
|
3月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
3月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
3月前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
4月前
|
程序员 编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(下)
动态内存分配与管理详解(附加笔试题分析)(下)
66 2
|
8月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
6月前
|
存储 安全 Go
Go 中的指针:了解内存引用
Go 中的指针:了解内存引用