zoukankan      html  css  js  c++  java
  • 指针作为形参和返回值的区别

    关于指作为针形参与返回值的常见问题

    1、返回栈中局部变量的地址

    #include <stdio.h>
    
    int *fun(){
        int a = 10; // a为当前方法栈中的局部变量,结束即释放
        return &a;  // 所以传递出去的会是一个无效(非法)地址
    }
    
    int main(int argc, char const *argv[])
    {
        int *a = NULL;
        a = fun();
        *a = 100;   // error,操作非法内存
        printf("a = %d
    ", *a);
        return 0;
    }

    2、返回data区的地址

    代码同上,不同之处在于a加个static,变为静态局部变量,等同于全局变量

    #include <stdio.h>
    
    int *fun(){
        static int a = 10; // 静态局部变量,不会随着方法栈自动释放
        return &a; // 返回的是有效地址
    }
    
    int main(int argc, char const *argv[])
    {
        int *a = NULL;
        a = fun();
        *a = 100;   // ok
        printf("a = %d
    ", *a);
        return 0;
    }

    3、指针作为形参传递(一)

    #include <stdio.h>
    #include <stdlib.h>
    
    void fun(int *tmp){
        tmp = (int *)malloc(sizeof(int));   // 形参局部指针变量只在当前方法栈中有效
        *tmp = 100;  // 当前栈中tmp动态分配的内存未释放,造成内存泄漏
    }
    
    int main(int argc, char const *argv[])
    {
        int *p = NULL;
        fun(p); // p是空指针,没有指向,把p的值传给tmp
        printf("*p = %d
    ", *p);    // error 操作空指针所指向的内存
        return 0;
    }    

    此时fun()函数和main()函数同级,tmp作为fun中的形参局部变量,对其操作不会影响main中的实参p;

    并且给tmp在堆中动态分配内存,但是tmp随着fun方法栈的释放而消失,堆中的内存没有释放,造成内存泄漏。

    4、指针作为形参传递(二)

    #include <stdio.h>
    #include <stdlib.h>
    
    void fun(int *tmp){
        *tmp = 100;
    }
    
    int main(int argc, char const *argv[])
    {
        int *p = NULL;
        p = (int *)malloc(sizeof(int));
        fun(p); // 值传递
        printf("*p = %d
    ", *p);    // 100
        return 0;
    }

    此时在fun()函数中操作的不是指针变量tmp,而是tmp所指向的堆内存(没有改形参本身),也就是fun()方法栈中和main()方法栈中的两个变量tmp和p指向了同一块堆内存,fun()方法栈的释放并不会影响操作结果

    5、指针作为返回值

    #include <stdio.h>
    #include <stdlib.h>
    
    int * fun(){
        int *tmp = NULL;
        tmp = (int *)malloc(sizeof(int));   // 在堆中分配内存
        *tmp = 100;                         // 堆内存赋值
        return tmp;                         // 返回堆区地址,函数调用完毕不释放
    }
    
    int main(int argc, char const *argv[])
    {
        int *p = NULL;
        p = fun(p);
        printf("*p = %d
    ", *p);    // 100
    
        // free :堆区空间需要手动释放
        if (p != NULL) {
            free(p);
            p = NULL;
        }
        
        return 0;
    }

    和第3的区别在于不是通过形参给变量赋值,而是直接返回了指针变量,注意:这里返回的不是栈区的局部变量地址(第1),而是堆区的地址,堆区变量是不会自动释放的,所以返回是合法的。

    指针指向同图4

  • 相关阅读:
    memcached(三)--参数
    memcached(二)--安装
    memcached(一)--前言
    如何高性能的给UIImageView加个圆角?(不准说layer.cornerRadius!)
    ios打包ipa的四种实用方法
    怎么调试EXC_BAD_ACCESS错误
    iOS应用性能调优的25个建议和技巧
    3D Touch
    segment
    低版本Xcode 出现could not find developer disk image问题
  • 原文地址:https://www.cnblogs.com/jixiaohua/p/11349112.html
Copyright © 2011-2022 走看看