zoukankan      html  css  js  c++  java
  • 从一段经典错误代码说起——关于局部变量指针和函数传参的问题分析

      有一段 精短的 错误代码 ,值得深思下:  
     
    voidGetMemory(char*p,int num)
    {
        p =(char*)malloc(sizeof(char)* num);
    }
    voidTest(void)
    {
        char*str = NULL;
        GetMemory(str,100);    
        strcpy(str,"hello");  
    }
      这段代码 明眼人一看就知道 有错误,可是真让他说原因,可能一时也说不明白,最直观地看法是:没有释放内存,造成了内存泄漏,但是 还远不止 如此。
    这个代码的深层错误原因 和 经典的 错误 swap()函数一样:
    void swap(int a,int b)
    {
        int c =0;
        c = a;
        a = b;
        b =c;
    }
    看了这两个类比的 例子,你应该就知道原因了,书面表达来说就是:
        函数参数其实都是 传值的,传值就意为着:参数 进入到函数体后 ,参与运算的 都是 这个 实际参数 的一份拷贝,对实参并没有起到 改变的作用,因此 不管是 GetMemory 还是swap,操作的 都是实参的 一份拷贝,回到了主调函数中,对实际参数根本没有起到 变动的作用,
    因此,GetMemory执行完毕后,str 的值仍然是NULL,swap后 ,a,b还是 a,b。
     
    为了达到 函数的功能 要求,你可能也知道 该怎么做,那就是 传 指针。传指针 并没有改变函数参数 是传值的 属性,但是 我们却可以通过操作指针即实参的地址 来达到改变 实参本身的目的。
     
    因此 GetMemory 可以写成
     
    voidGetMemory(char**p,int num)
    {
       *p =(char*)malloc(sizeof(char)* num);
    }

      调用时  将str的指针 传进来 就可以了。

    同理 :swap 也要改写成:
        
    void swap(int*a,int*b)
    {
        int c =0;
        c =*a;
        *a =*b;
        *b =c;
    }
    传参数 时 需要 给出 a和b的 地址即可。
     
    回到 标题,局部变量指针 实际上 有两种情形:
    1.指向 堆区 ,如 :char *ptr = (char*)malloc(20);
    2.指向 栈区   ,如,char ptr[] = "hello world";
    当以上代码 写在函数中时,只有 指向堆区的 指针可以合理合法的作为 返回值,而指向 栈区的指针的内容 因为 函数的返回 而被回收,即使将该指针作为返回值,也达不到预期的效果。这是 堆区和栈区的本质区别。
     
    因此,最终的,我们可以将 GetMemory函数 无二级指针化,即:
    char*GetMemory(int num)
    {
        char*p = NULL;
        p =(char*)malloc(sizeof(char)* num);
        return p;
    }
    最后的最后,请一定要注意 释放内存。这个内存的释放 需要在主调函数中去做了。
     
    这里 没有遵守 “谁申请,谁释放”的 原则。
     
     
     
     
     
  • 相关阅读:
    内网安全隐藏通信隧道基础&&网络通信隧道之一ICMP隧道
    windows server2012 r2 .net framework 3.5失败
    awvas启动不起来解决方案
    Kali Linux解压包命令:
    kali linux 中python2不带pip的解决方法
    内网渗透信息收集
    团队作业(二):需求分析
    ORA00600: internal error code, arguments: [16513], [1403] 恢复
    helpyouhelpyou@cock.li 加密数据库恢复
    合成孔径雷达成像——算法与实现内容简要:第1章
  • 原文地址:https://www.cnblogs.com/Stultz-Lee/p/6732014.html
Copyright © 2011-2022 走看看