指针作为形参和返回值的区别

Posted jixiaohua

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针作为形参和返回值的区别相关的知识,希望对你有一定的参考价值。

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

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\\n", *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\\n", *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\\n", *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\\n", *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\\n", *p);    // 100

    // free :堆区空间需要手动释放
    if (p != NULL) 
        free(p);
        p = NULL;
    
    
    return 0;

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

指针指向同图4

以上是关于指针作为形参和返回值的区别的主要内容,如果未能解决你的问题,请参考以下文章

引用与指针的区别

数组与指针的区别,以及在STL中传递数组/指针

求教C语言指针作为实参取不到值的问题

传入参数 指针 引用和 什么都不加的区别

函数形参为指针与非指针的区别

C中数组在函数中形参和实参的区别