• C语言:动态内存分配(3)


    常见的动态内存错误:

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

    void test()
    {
        int*p=(int*)malloc(INT_MAX/4);
        *p= 20;//如果p的值是NULL,就会有问题
        free(p);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

    void test()
    {
        int a=10;
        int *p=&a;
        free(p);//定义的a是栈区的,不能用free释放
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    void test()
    {
        int*p=(int*)mal1oc(100);
        p++;
        free(p);//p不再指向动态内存的起始位置
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5、对同一块动态内存多次释放

    void test()
    {
        int *p= (int*)malloc(100);
        free(p);
        free(p);//重复释放
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    6、动态开辟内存忘记释放(内存泄露)

    while(1)
    {
       malloc(1);//内存不释放,占的内存会越来越大
    }
    
    • 1
    • 2
    • 3
    • 4

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

    下面有四道关于动态内存分配错误的笔试题:
    第一题:

    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 () ;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    答:该程序是错误的。因为test运行之后,p申请的内存空间其实并没有给到str,因此str无法打印出hello world。而且p申请的内存并没有进行free操作,造成了内存泄漏。

    第二题:

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    答:该程序是有问题的。该题虽然return p了,但是在GetMemory函数结束之后,p销毁了。因此p成为了野指针。

    第三题:

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    答:该程序存在内存泄漏问题,没有free释放。但是该题可以正常打印出hello,因为vp接收的是str的地址,因此p申请到内存空间时,str就是其首地址。因此可以打印出。

    第四题:

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    答:该程序free提前释放了,释放完后再将world字符拷贝进去,可是那块空间已经不属于str了,造成了非法访问。结构虽然能打印出world,但是还是有问题存在的。

  • 相关阅读:
    前端知识粉碎机
    画一条0.5px的线、设置小于12px的字体、解决 1px 问题
    射频识别技术课程实验--模拟串口间的通信--基础实验
    Redis缓存击穿、雪崩、穿透
    Day27——39. 组合总和 40.组合总和II 131.分割回文串
    1667. 修复表中的名字
    Javaweb实现数据库简单的增删改查
    如何将MNIST数据集数据图像可视化
    RFSoC应用笔记 - RF数据转换器 -05- RFSoC关键配置之RF-ADC内部解析(三)
    【SpringBoot实战】视图技术-Thymeleaf
  • 原文地址:https://blog.csdn.net/qq_57430594/article/details/128158186