今天,看到一个笔试题,题目是:
void GetMemory(char **p,int num)
{
*p=(char *)malloc(num);
}
int main()
{
char *str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
free(str);
if(str!=NULL)
{
strcpy(str,"world");
}
printf("\n str is %s",str);
getchar();
}
问输出结果是什么?
结果输出是“world”;具体分析见上一篇文章:c笔试面试题。
但是自己自以为然,写成了这:
void GetMemory(char *p,int num)
{
p=(char *)malloc(num);
}
int main()
{
char *str=NULL;
GetMemory(str,100);
strcpy(str,"hello");
free(str);
if(str!=NULL)
{
strcpy(str,"world");
}
printf("\n str is %s",str);
getchar();
}
结果运行错误了。在网上找到了相似的,现在终于明白了原来是这么回事:毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p=p。函数GetMemory申请内存后,其内存地址被赋给的是_p,而不是*p,如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。但是在本例中p丝毫未变。所以函数GetMemory并不能输出任何东西。
这是属于指针参数传递内存方法没理解。如果非得用指针去申请内存,应该用“指向指针的指针”或者“指针的引用”。最上面的那例子就是使用了指向指针的指针。下面讲讲用指针的引用来实现:
简单的说,如果不使用引用的话,被传递的参数是不能被修改的,即使传递的参数是一个指针,也只能修改指针指向的内容,但是不能修改指针本身。这是因
为无论你传值还是传指针,函数都会生成一个临时变量,但传引用时,不会生成临时变量。在所给出的程序中,传递的参数是一个指针,其中试图修改这个指针的值
(即为其分配一段内存),因而是不能成功的。
而若使用指针的引用,在函数中不会生成临时变量,直接对指针的值进行修改/赋值,可以达到目的。若使用二级指针**p(指向指针的指针),虽然不能
修改二级指针p的值,但是在函数中可以修改p所指向的内容的值,也就是一级指针*p的值,当然在main函数中需要的实参就是str的地址。正确程序如下:
void GetMemory(char *&p,int num)
{
p=(char *)malloc(num);
}
int main()
{
char *str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
free(str);
if(str!=NULL)
{
strcpy(str,"world");
}
printf("\n str is %s",str);
getchar();
}
参考:
http://hi.baidu.com/dignity99/blog/item/9ab486168357590ec93d6dc0.html。
阅读(1401) | 评论(0) | 转发(0) |