#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

#include <stdlib.h>

int func1(int *a)

{

    a = new int;

    *a = 1;

    printf(“func1 addr a=%p\n”,a);

    return *a;

}

int func2(int **a)

{

    *a = new int;

    **a = 10;

    //如果是指针的指针,那函数内可以对指针的指针直接赋值

    //那返回的地址就彻底悲剧了,函数外面的指向彻底乱了


    //int i = 0,*b = 0;

    //b = &i;

    //对指针的指针直接赋值,有可能不这么直接,间接被修改

    //a = &b;

    printf(“func2 addr a=%p,*a=%p\n”,a,*a);

    return **a;

}

//*&: 运算符*优先级高于&,两个运算符都是从右向左结合运算;//所以,*&a 的意思就是先运算 *,得到 指针,再通过 &,获取指针的引用

//typedef int * INT_P;INT_P a 等同于 int *a,那 INT_P &a 就等同于 int *&a,也即指针的引用了

int func3(int *&a)

{

    a = new int;

    *a = 100;

    //int i = 0,*b = 0;

    //b = &i;

    //因为是指针的引用,不能对其进行赋值

    //确保了函数调用完成后,地址指向不会乱

    //&a = &b;

    printf(“func3 addr a=%p,&a=%p\n”,a,&a);

    return *a;

}

int main (int argc, char *argv[])

{

     int a = 0,*p = 0;

     a = func1(p);

     printf(“a=%d,addr a=%p,addr p=%p,&p=%p\n\n”,a,&a,p,&p);

     a = func2(&p);

     printf(“a=%d,addr a=%p,addr p=%p,&p=%p\n\n”,a,&a,p,&p);

     a = func3(p);

     printf(“a=%d,addr a=%p,addr p=%p,&p=%p\n\n”,a,&a,p,&p);

     printf (“%s\r\n”, “finish”);

     return 0;

}

/*

编译执行

g++ -m32 -g aa.c -o aa;./aa

func1 addr a=0x9fc3008

a=1,addr a=0xffc59bdc,addr p=(nil),&p=0xffc59bd8

func2 addr a=0xffc59bd8,*a=0x9fc3018

a=10,addr a=0xffc59bdc,addr p=0x9fc3018,&p=0xffc59bd8

func3 addr a=0x9fc3028,&a=0xffc59bd8

a=100,addr a=0xffc59bdc,addr p=0x9fc3028,&p=0xffc59bd8

finish

*/

/*

func1:

[&p=0xffc59bd8]—–>[p=null]——>null

func2:

[&p=0xffc59bd8]—–>[p=0x9fc3018]——>10

func3:

[&p=0xffc59bd8]—–>[p=0x9fc3028]——>100

1. 函数 func1 调用后,func1函数内部内存泄漏,返回的指针还是无效;

2. 函数 func2 调用后,返回了合法的地址,其指针的地址也完全匹配;

3. 函数 func3 调用后,返回了合法的地址,其指针的地址也完全匹配;

注意看 &p=0xffc59bd8 的地址一直不变,但是p的指向一直再变,实际可以用

一个简单的映射描述:

int **pp = 5;

[pp=0x***]—->[*pp=0x****]—->[**p = 5]

*/


版权声明:本文为hzhxxx原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/hzhxxx/article/details/28874545