Chinaunix首页 | 论坛 | 博客
  • 博客访问: 204083
  • 博文数量: 27
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 350
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-22 08:34
文章分类

全部博文(27)

文章存档

2011年(1)

2010年(1)

2009年(25)

我的朋友

分类: C/C++

2009-10-22 20:09:35

今天,看到一个笔试题,题目是:
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) |
给主人留下些什么吧!~~