经典的动态内存错误(上)

一、前言
       我们在使用动态内存函数申请内存空间时,需要注意许多细节如函数的返回值,

所申请空间的释放等等,我们要是忽略这些细节就容易造成程序崩溃、内存泄漏、

非法访问等等一些程序问题。

二、内存错误的类型
1.未判断动态内存函数的返回值造成非法访问
#include<stdio.h>
 
#include<malloc.h>
 
#include<stdlib.h>
 
int main()
{
    int *p=(*int)malloc(10*sizeof(int));//申请10个int类型的空间也可以写成malloc(40)
 
    for(int i=0;i<10;i++)//在此之前未进行返回值判断,如果是返回值是NULL(申请失败返回的),*NULL是 
                       //   非法访问的因为NULL的的地址是随机的未定的。
         { 
           
           int kc=*(p+i)=i;//赋值
           printf("%d ",kc);//赋值一个打印一个
         }
 
           free(p);
           p=NULL;
          system("pause");//暂停
          return 0;
}
所以使用动态内存函数时应该先判断为非空指针才可以进行后续一系列操作

判断方法是

//加个
if(*p!=NULL)
    { 
      //要执行的语句
 
    }
    else
      {
         return 0;//为NULL直接退出函数
     
      }
2.赋值的数大于申请的内存空间造成的越界访问
#include<stdio.h>
 
#include<stdlib.h>
 
int main()
 {
   char* pp=(char*)calloc(5,sizeof(char));//申请5个char类型的内存空间
    if(pp!=NULL)
      {
        for(int i=0;i<=5;i++)//赋值了6个元素分别是0、1、2、3、4、5动态函数只申请了5个
                            // 剩余一个已经越界访问了。
          {
             int yy =*(pp+i)=i;
              printf("%d ",yy);
          }
      }
    else
     {
         return 0;//为空直接退出函数
 
     }
      free(pp);//老规矩,释放申请的地址,下面那个给你们说
      pp=NULL;
     system("pause");
     return 0;
 }
  下图时非法访问的报错,虽然赋值了,但是呢那块空间本不属于我们的,但我们强行赋值,

  故造成非法访问,所以我们在写代码时要格外注意申请的大小和使用的多少,

    前者须大于等于后者

 3.free函数未完全释放
主要原因是返回的的指针不在指向初始位置,或者说指针已经发生了变化

#include<stdio.h>
 
#include<stdlib.h>
 
int main()
{
     int* ptr=(int*)malloc(10*sizeof(int));//你们应该很熟了,我这里就不全部注释了
    
      if(ptr!=NULL)
       {
          for(int i=0;i<10;i++)
             {
               int nb=*ptr++=i;//ptr结束后指向最后一个元素
               printf("%d ",nb);
             }
       }
        free(ptr);//此时ptr已经不再指向初始位置了,导致free不能完全释放(释放了,但没完全释放哈哈)
        ptr=NULL;
       return 0;
}
以下是出错报的警告(未完全释放会导致内存泄漏)

 改正这个错误其实不难,因为他是不记得原来的首地址,所以我们只需要在他改变之前存下

首地址如int* ret=ptr然后释放ret就可以了.

具体如下:

#include<stdio.h>
 
#include<stdlib.h>
 
int main()
{
    int* ptr = (int*)malloc(10 * sizeof(int));
    int *ret = ptr;
    if (ptr != NULL)
    {
        
        for (int i = 0; i<10; i++)
        {
            int nb = *ptr++ = i;
            printf("%d ", nb);
        }
    }
    free(ret);
    ret=NULL;
    system("pause");
    return 0;
}
写作不易,记得支持一下,欢迎各位大佬斧正
————————————————
版权声明:本文为优快云博主「执久呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_60719453/article/details/120138836

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值