使用指针做函数返回值和指针作函数参数问题
2017-09-28 10:12
645 查看
一、使用指针做函数返回值:
1、当使用指针做为函数的返回值时,主函数处的char *p;将获得调用函数char *pf;的值,即一个地址值,如oxAE72。此时需要我们注意的是该地址值所指向的空间是否存在(即已向操作系统声明注册,不会被释放,即可能被其他操作修改);
2、使用栈内存返回指针是明显错误的,因为栈内存将在调用结束后自动释放,从而主函数使用该地址空间将很危险。
3、使用堆内存返回指针是正确的,但是注意可能产生内存泄露问题,在使用完毕后主函数中释放该段内存。
二、使用指针做函数参数:
1、有的情况下我们可能需要需要在调用函数中分配内存,而在主函数中使用,而针对的指针此时为函数的参数。此时应注意形参与实参的问题,因为在C语言中,形参只是继承了实参的值,是另外一个量(ps:返回值也是同理,传递了一个地址值(指针)或实数值),形参的改变并不能引起实参的改变。
2、直接使用形参分配内存的方式显然是错误的,因为实参的值并不会改变,如下则实参一直为NULL:
3、由于通过指针是可以传值的,因为此时该指针的地址是在主函数中申请的栈内存,我们通过指针对该栈内存进行操作,从而改变了实参的值。
4、根据上述的启发,我们也可以采用指向指针的指针来进行在调用函数中申请,在主函数中应用。如下:假设a的地址为ox23,内容为'a';而str的地址是ox46,内容为ox23;而pstr的地址是ox79,内容为ox46。
我们通过调用函数GetMemory,从而将pstr的内容赋给了p,此时p = ox46。通过对*p(ox23)的操作,即将内存地址为ox23之中的值改为char[100]的首地址,从而完成了对char* str地址的分配。
当我们释放掉一个指针p后,只是告诉操作系统该段内存可以被其他程序使用,而该指针p的地址值(如ox23)仍然存在。如果再次给这块地址赋值是危险的,应该将p指针置为NULL。
调用函数删除主函数中的内存块时,虽然可以通过地址传递直接删除,但由于无法对该指针赋值(形参不能传值),可能造成悬浮指针,所以此时也应该采用指向指针的指针的形参。例如:
转自http://blog.chinaunix.net/uid-24372973-id-293635.html
1、当使用指针做为函数的返回值时,主函数处的char *p;将获得调用函数char *pf;的值,即一个地址值,如oxAE72。此时需要我们注意的是该地址值所指向的空间是否存在(即已向操作系统声明注册,不会被释放,即可能被其他操作修改);
2、使用栈内存返回指针是明显错误的,因为栈内存将在调用结束后自动释放,从而主函数使用该地址空间将很危险。
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); }
转自http://blog.chinaunix.net/uid-24372973-id-293635.html
相关文章推荐
- c/c++使用指针做函数返回值和指针作函数参数问题
- c/c++使用指针做函数返回值和指针作函数参数问题
- 使用指针做函数返回值和指针作函数参数问题
- 指针数组作为函数参数的使用问题
- 函数调用缺少参数列表;请使用“&Student::Printf”创建指向成员的指针 问题解析
- 实例解析使用指针作为函数参数传递需要注意的问题
- 44. 腾讯面试题: 使用函数的参数指针,分配内存空间问题
- 使用指针作为函数返回值和参数的问题总结
- 函数传出参数,用指针作为函数的传出参数实现多值返回
- asp.net c#的传参中经常使用到中文参数的处理,下面的函数可以解决中文参数的问题
- 使用指针从函数返回一个二维数组
- 函数参数的传递问题(指针的指针)(转)
- [转]PHP使用empty检查函数返回结果时报Fatal error: Can't use function return value in write context的问题
- 三个学生四门课程的问题(返回指针值的函数)
- 二维数组做函数参数,如何将三维数组降为二维数组,指向数组的指针的使用
- 约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
- 用指针传递函数参数的问题
- 指针作为函数参数相关问题
- 对引用和指针使用以及函数返回引用和指针类型的理解
- 函数参数的传递问题(一级指针和二级指针)