当前位置: 首页 > article >正文

笔记-常见的动态内存错误

1.对NULL指针的解引用操作

void test()
{
    int *p = (int *)malloc(INC_MAX/4);//当p的值为NULL时,就会有问题。
    *p = 20;
    free(p);
}

malloc函数返回值需要判断。

2.对动态开辟空间的越界访问

void test()
{
   int i = 0;
   int *p = (int *)malloc(10*sizeof(int));
   if(NULL == p)
    {
       exit(EXIT_FAILURE);
    }
   for(i = 0; i <= 10; i ++)
    {
       *(p + i) = i;//当i = 10时越界访问
    }
   free(p);
}

3.对非动态开辟内存使用free释放

void test()
{
   int a = 10;
   int *p = &a;
   free(p);//释放不了,程序会崩!!!
}

4.使用free释放一块动态开辟内存的一部分

void test()
{
   int *p = (int *)malloc(100);
   p ++;
   free(p);//p不再指向动态内存的起始位置
}

5.对同一块动态内存进行多次释放

对人协作的情况下,要注意其他人是否已经释放,避免重复释放和不释放的情况。

void test()
{
   int *p = (int *)malloc(sizeof(100));
   free(p);
   free(p);//重复释放
}

6动态开辟内存忘记释放

在一般情况下,如果不使用free释放,程序结束之后,也会由操作系统回收。

但是在未使用free函数,程序又无法终止的情况下,这块开辟的内存无法被找到和使用,就会产生内存泄漏的情况。

void test()
{
   int *p = (int *)malloc(sizeof(100));
   if(NULL != p)
     {
         *p = 20;
     }
}
int main()
{
   test();
   while(1);//程序无法结束,而且也没有使用free函数释放,所以会造成内存泄露。
}

几个经典的笔试题

第一道:

void GetMemory(char *p)
{
   p = (char *)malloc(100).
   //p是str的一份临时拷贝,所以在退出函数的时候会被销毁,但是由malloc申请的空间还没有被free释放,所以导致空间虽然存在,但是无法通过p找到并使用,由此产生了内存泄漏的现象。
}

void test()
{
   char *str = NULL;
   GetMemory(str);
   //传递的是变量本身,所以是传值调用,返回后str仍然是空指针。
   strcpy(str,"hello world");
   //将hello world通过解引用操作拷贝到str当中,但是对NULL指针进行解引用就导致了程序崩溃。
   printf(str);
   //使用printf函数对字符串进行打印的时候,可以直接将地址传进去
}

修改方式:

1. 

char *GetMemory()
{
   char *p = (char *)malloc(100).
   return p;
}

void test()
{
   char *str = NULL;
   str = GetMemory();
   strcpy(str,"hello world");
   printf(str);
}

2.

void GetMemory(char **p)
{
   *p = (char *)malloc(100);
}

void test()
{
   char *str = NULL;
   GetMemory(&str);
   strcpy(str,"hello world");
   printf(str);
}

 第二道:返回栈空间地址的问题

char *GetMemory(void)
{
   char p[] = "hello world";
   //此函数内部创建的数据是在栈区的临时数据,在退出函数后将归还给内存,但是这里将这块空间的地址返回了
   return p;
}
 
void test()
{
   char *str = NULL;
   str = GetMemory();
//因为传给str的地址所指向的空间内容已经归还了,所以里面的内容可能已经被修改了,此时并不再是hello world 了,所以通过str访问并打印出来的结果是未知字符。
   printf(str);
}

 第三道:

void test()
{
   char *str = (char *)malloc(100);
   strcpy(str,"hello");
   free(str);
   //释放了str动态申请的空间后,空间已经被归还给操作系统,但是str仍然指向空间首段地址。
   if(str != NULL)
    {
       strcpy(str,"world");//这里对已经释放的空间进行解引用操作,造成了非法访问
       printf(str);//虽然是非法访问,但是结果是可以输出world的
    }
}

解决办法就是在free函数后面,将str指针置空。


http://www.kler.cn/a/8007.html

相关文章:

  • 机器学习【激活函数】
  • 【MySQL】MySQL函数之JSON_EXTRACT
  • 45.第二阶段x86游戏实战2-hook监控实时抓取游戏lua
  • 【计算机网络】【网络层】【习题】
  • Java设计模式面试题及参考答案
  • 机器学习基础02_特征工程
  • 收割offer疯狂涨了5K,自动化测试面试题整理大全,你能答上多少?
  • js设计模式——组合模式
  • RBF-UKF径向基神经网络结合无迹卡尔曼滤波估计锂离子电池SOC(附MATLAB代码)
  • 在cmd命令窗口安装Python模块
  • 入门力扣自学笔记257 C++ (题目编号:1041)
  • GuLi商城-SpringCloud-Gateway网关核心概念、测试API网关
  • 探索三维世界:从Hello World开始的Three.js入门之旅
  • 硬件语言Verilog HDL牛客刷题day07 计数器与存储器部分
  • 亚马逊美国站严查磁体产品?亚马逊最新政策公布
  • 67页新型智慧城市整体规划建设方案
  • Thinkphp 6.0模版的循环标签
  • ToBeWritten之反入侵安全技术面经总结
  • JSON 数据解析的3种方式
  • 2022国赛24:linux基础配置和本地源创建
  • Transformer中的注意力机制及代码
  • 动态规划之线性DP
  • 基于凸集上投影(POCS)的聚类算法
  • Pycharm用ssh连接GCP以后,可以项目都放在本地,只是调用GCP的计算资源吗?
  • Vue+springboot+java学生成绩动态追踪系统课程资源课件下载设计与实现
  • 【Python】【进阶篇】三、Python爬虫的构建User-Agnet代理池