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

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

野指针重点总结

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

✔什么情况会出现野指针

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

结语

如果对您有帮助的话,

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

如果对您有帮助的话,

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

如果对您有帮助的话,

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

相关文章
|
27天前
|
编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(上)
动态内存分配与管理详解(附加笔试题分析)
45 1
|
3月前
|
存储 C语言
指针和动态内存分配
指针和动态内存分配
93 0
|
27天前
|
程序员 编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(下)
动态内存分配与管理详解(附加笔试题分析)(下)
44 2
|
5月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
3月前
|
存储 安全 Go
Go 中的指针:了解内存引用
Go 中的指针:了解内存引用
|
4月前
|
运维
开发与运维数组问题之指针的加减法意义如何解决
开发与运维数组问题之指针的加减法意义如何解决
42 7
|
4月前
|
存储 C++ 运维
开发与运维数组问题之指针的定义语法如何解决
开发与运维数组问题之指针的定义语法如何解决
34 6
|
5月前
|
存储 C++
有关【指针运算】的经典笔试题
有关【指针运算】的经典笔试题
31 4
|
5月前
|
程序员 C语言 C++
【C语言基础】:动态内存管理(含经典笔试题分析)-2
【C语言基础】:动态内存管理(含经典笔试题分析)
|
5月前
|
程序员 编译器 C语言
【C语言基础】:动态内存管理(含经典笔试题分析)-1
【C语言基础】:动态内存管理(含经典笔试题分析)