使用指针做函数返回值和指针作函数参数问题


             使用指针做函数返回值和指针作函数参数问题 2010-09-20 19:35:41

分类: C/C++

一、使用指针做函数返回值:
 
1、当使用指针做为函数的返回值时,主函数处的char *p;将获得调用函数char *pf;的值,即一个地址值,如oxAE72。此时需要我们注意的是该地址值所指向的空间是否存在(即已向操作系统声明注册,不会被释放,即可能被其他操作修改);

2、使用栈内存返回指针是明显错误的,因为栈内存将在调用结束后自动释放,从而主函数使用该地址空间将很危险。
[code] 


            char* GetMemory()
            {
               char p[] = "hi";
               return p;
             }           
            void main()
            {
               char *str = GetMemory(); //出错! 得到一块已释放的内存
               printf(str);
            }



3、使用堆内存返回指针是正确的,但是注意可能产生内存泄露问题,在使用完毕后主函数中释放该段内存。 

   例如: 

            char* GetMemory()
            {
                char *p = new char[100];
                return p;
            }
            void main()
            {
                char *str = GetMemory();
                delete [] str; //防止内存泄露!
            }



二、使用指针做函数参数: 

1、有的情况下我们可能需要需要在调用函数中分配内存,而在主函数中使用,而针对的指针此时为函数的参数。此时应注意形参与实参的问题,因为在C语言中,形参只是继承了实参的值,是另外一个量(ps:返回值也是同理,传递了一个地址值(指针)或实数值),形参的改变并不能引起实参的改变。 

2、直接使用形参分配内存的方式显然是错误的,因为实参的值并不会改变,如下则实参一直为NULL: 

            void GetMemory(char* p)
            {
               char *p = new char[100];
            }
            void main()
            {
               char *str;
               GetMemory(str);
               strcpy(str, "hi"); // str = NULL
            }


3、由于通过指针是可以传值的,因为此时该指针的地址是在主函数中申请的栈内存,我们通过指针对该栈内存进行操作,从而改变了实参的值。 


            void Change(char *p)
            {
               *p = 'b';
            }
            void main()
            {
               char a = 'a';
               char* p = &a;
               Change(p);
               printf("%c\n", a);           //值a改变! 

            }


4、根据上述的启发,我们也可以采用指向指针的指针来进行在调用函数中申请,在主函数中应用。如下:假设a的地址为ox23,内容为'a';而str的地址是ox46,内容为ox23;而pstr的地址是ox79,内容为ox46。 

   我们通过调用函数GetMemory,从而将pstr的内容赋给了p,此时p = ox46。通过对*p(ox23)的操作,即将内存地址为ox23之中的值改为char[100]的首地址,从而完成了对char* str地址的分配。 


            void GetMemory(char** p)
            {
                char *p = new char[100];
            }   

            void main()
            {
                char a = 'a';
                char* str = &a;
                char** pstr = &str;
                GetMemory(pstr);
                strcpy(str, "hi");
            }



5、注意指针的释放问题,可能形成悬浮指针。 

   当我们释放掉一个指针p后,只是告诉操作系统该段内存可以被其他程序使用,而该指针p的地址值(如ox23)仍然存在。如果再次给这块地址赋值是危险的,应该将p指针置为NULL。 

   调用函数删除主函数中的内存块时,虽然可以通过地址传递直接删除,但由于无法对该指针赋值(形参不能传值),可能造成悬浮指针,所以此时也应该采用指向指针的指针的形参。例如: 

            void MemoryFree(char** p)
            {
                delete *p;
                *p = NULL;
            }
            void main()
            {
                char *str = new char[100];
                char *pstr = &str;
                MemoryFree(pstr);
            }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值