CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

请问:一道笔试题

楼主goodsun2()2005-12-18 19:09:19 在 C/C++ / C语言 提问

程序1:  
  char   *GetMemory()  
  {  
  char   p[]="hello   world";  
  return   p;  
  }  
   
  void   Test(void)  
  {  
  char   *str=NULL;  
  str=GetMemory();  
  printf(str);  
   
  }  
   
  程序2:  
  void   GetMemory(char*   p)  
  {  
  p=(char*)malloc(100);  
  }  
   
  void   Test(void)  
  {  
  char   *str=NULL;  
  GetMemory(str);  
  strcpy(str,"hello   world");  
  printf(str);  
  }  
   
  请问这两个程序的输出结果有什么不同? 问题点数:10、回复次数:37Top

1 楼dx30611(想要clean code)回复于 2005-12-18 19:14:08 得分 0

当然不一样  
  第一个地址是"hello   world"字符串的首地址  
  第二个是堆内存中分配的地址Top

2 楼steedhorse(晨星)回复于 2005-12-18 19:19:07 得分 0

第二个不好吧,C语言参数都是值传递,函数内部对参数的改变不影响外部的实参。Top

3 楼dte99(善善恶恶)回复于 2005-12-18 19:37:11 得分 0

第一个程序是错误的,getmemory函数中的"Hello   world"字符串是局部变量,调用完之后即被释放,因此输出的是一段随机数据,不是"HEllo   world";  
  第二个程序则可以,因为malloc分配的内存如果不free掉的话,是不会被释放的,因此可以正常输出"Hello   world",但是因为第二个程序中没有free,所以有内存泄漏的问题。  
  Top

4 楼dte99(善善恶恶)回复于 2005-12-18 19:41:33 得分 0

因此虽然理论上可以正常输出,但是实际上会因为内存泄漏问题导致strcpy程序异常而程序异常退出。Top

5 楼zhangxiaoyou(弱水三千)回复于 2005-12-18 20:58:23 得分 0

!新手报到了啊   .Top

6 楼ak_2005(★★★★★)回复于 2005-12-18 21:01:03 得分 0

同意   dte99(善善恶恶)    
   
  char   *str=NULL;//要报NULL   pointer   assignment  
  改为:    
  char   *str;//就不会了Top

7 楼goodsun2()回复于 2005-12-19 01:20:57 得分 0

为什么:  
  char   *str=NULL;//要报NULL   pointer   assignment  
  改为:    
  char   *str;//就不会了?Top

8 楼afei_xyd(阿飞)回复于 2005-12-19 10:03:09 得分 0

第一个程序输出结果可能是乱码,因为GetMemory()返回的是指向栈内存得指针,该指针得地址不是NULL,但是内容已经被删除。  
  第二个程序将会崩溃,因为GetMemory()并不能传递动态分内存,Test()中str   一直是NULL,  
  strcpy(str,"hello   world");将会使程序崩溃Top

9 楼Z_X_H(李逍遥)回复于 2005-12-19 11:34:33 得分 0

第一个程序返回一个局部变量的地址是无定义的,编译器会给出一个警告,虽然程序可正常运行,但输出内容不确定.  
  第二个程序不能正常运行,因为strcpy(str,"hello   world");中str为NULL.虽然调用了GetMemory,但是参数还是按值传递,程序会生成一个指针的拷贝,并不会改变原来指针的值.可以用指针的引用或指针的指针代替,如void   GetMemory(char*&   p)或void   GetMemory(char**   p);Top

10 楼yan_1103(超越自我)回复于 2005-12-19 14:27:12 得分 0

是不是金智的笔试啊?Top

11 楼Acoolice()回复于 2005-12-19 16:36:20 得分 0

第一个输出是乱码;  
  第二个不能正常的运行!!Top

12 楼goodsun2()回复于 2005-12-20 00:39:42 得分 0

char   *str=NULL;  
  和char   *str;有什么不同?Top

13 楼langzi520(虽左但右)回复于 2005-12-20 16:44:36 得分 0

不晓得那位是标准答案啊!Top

14 楼mccxj(老鼠不逛街)回复于 2005-12-20 16:58:46 得分 10

程序1:  
  char   *GetMemory()  
  {  
  char   p[]="hello   world";  
  return   p;  
  }  
   
  void   Test(void)  
  {  
  char   *str=NULL;  
  str=GetMemory();  
  printf(str);  
  }  
  GetMomory()返回临时变量的地址..调用完了之后内容被清除,所以str只能得到一个  
  未知内容..乱码!  
   
   
  程序2:  
  void   GetMemory(char*   p)  
  {  
  p=(char*)malloc(100);  
  }  
   
  void   Test(void)  
  {  
  char   *str=NULL;  
  GetMemory(str);  
  strcpy(str,"hello   world");  
  printf(str);  
  }  
   
  程序崩溃..因为只是在栈里边分配空间..GetMomory之后空间已经被回收..所以strcpy不能成功..  
   
  请问这两个程序的输出结果有什么不同?  
   
  这两个题目出自林锐的c/c++高质量编程一书,可以上网查找..Top

15 楼zjfeng1984(海诺)回复于 2005-12-20 19:14:07 得分 0

新手报道Top

16 楼zjfeng1984(海诺)回复于 2005-12-20 19:24:02 得分 0

笔试题考的太细致了,看来我又的好好的记些东西了   哎!!学海无崖Top

17 楼snailbreak(悄悄的来,正如我悄悄的走)回复于 2005-12-20 20:19:10 得分 0

第一题大家讲的都很好,  
  我讲讲对第二题的看法:  
  void   GetMemory(char*   p)  
  {  
  p=(char*)malloc(100);  
  }  
   
  void   Test(void)  
  {  
  char   *str=NULL;  
  GetMemory(str);//调用GetMemory函数是用str初始化形参p,p改变了,申请的空间  
  //的首地址也赋给了p,但是没有返回个str  
  strcpy(str,"hello   world");//所以到这一步str仍然我NULL,执行strcpy就会出现异常,  
  //而且申请的空间也有泄露问题  
  printf(str);  
  }  
   
  修改成这样就好了:  
  char*   GetMemory(char*   p)  
  {  
  p=(char*)malloc(100);  
  return   p;  
  }  
   
  void   Test(void)  
  {  
  char   *str=NULL;  
  str=GetMemory(str);  
  strcpy(str,"hello   world");  
  printf(str);  
  }  
   
  象这样的问题在C++中用引用可以避免。  
  Top

18 楼kundy(在旅途)回复于 2005-12-20 23:11:16 得分 0

snailbreak(南师杀猪的)   ,补充一下:  
  void   Test(void)  
  {  
      char   *str   =   NULL;  
      str   =   GetMemory(str);  
      strcpy(str,"hello   world");  
      printf(str);  
   
      free(str)     /*这里应该加上,否则内存泄漏*/  
  }  
   
  说明:当调用GetMemory()函数时,str变量的值通过参数传值的方式赋给GetMemory()的局部参数p。在函数GetMemory()中调用malloc()函数在系统堆中返回一块内存,内存的首地址赋给了指变量针p。GemMemory()返回时将p所赋的地址赋给了Test()中的变量str,从而str指向了堆中的那块内存。在使用完后应该释放,否则有内存泄漏。  
  Top

19 楼yclr(雪阳)回复于 2005-12-21 13:50:00 得分 0

呵呵,大家都分析的好细呀  
  Top

20 楼cdo(Everything has a favourable turn)回复于 2005-12-21 14:32:58 得分 0

这些可以看看林锐的《高质量C++编程》Top

21 楼bm1408(向va_list学习~不用VC好多年~)回复于 2005-12-21 15:01:22 得分 0

高质量的C++编程上说的还可以吧(:Top

22 楼wcg_jishuo()回复于 2005-12-24 21:12:38 得分 0

是不是把c语言真真理解要   把汇编学好?,软件设计师   习题中那个汇编是什么汇编语言/?  
          大家     介绍几本好的汇编的书?Top

23 楼rockhard(不签名)回复于 2005-12-24 21:38:05 得分 0

第一题有可能输出"hello   word"尽管这个程序是错误的,  
  char   *GetMemory()  
  {  
  char   p[]="hello   world";  
  return   p;  
  }  
  此处的   p是在栈中分配的局部变量,函数返回后这块内存会被回收。  
  (华为的笔试题目里面有这道题)  
   
  第二个根本就是错误的。  
  char   *str=NULL;  
  GetMemory(str);  
  strcpy(str,"hello   world");   //此处的str值仍然是NULL,你可以在调试器下看看  
  因此程序一运行就会报错,非法访问。  
  要弄清楚值传递与引用传递的差别  
  Top

24 楼hanxuaiztt(依旧飘流)回复于 2005-12-24 22:26:15 得分 0

我只知道用了malloc,后面就应该用一个free。其他的我真的不只到还有什么了  
  哎,没个老师指导我就是菜啊!Top

25 楼yk9394(空)回复于 2005-12-24 22:47:49 得分 0

华为面试题中有这样一题Top

26 楼nagon()回复于 2005-12-24 23:05:12 得分 0

两个都有问题啊。区别是第一个可以跑,第二个不能跑。  
  这种和编译器平台关系不大的东东用VC跑跑看嘛。Top

27 楼chengzanmiao(高薪為共產當多納稅)回复于 2005-12-25 11:19:40 得分 0

GetMemory()  
  这样用根本得不到函数内分配的内存,返回一个不确定的地址.Top

28 楼yleiou(单刀匹马)回复于 2005-12-25 11:49:23 得分 0

解析的都很好Top

29 楼ruiding(瑞丁)回复于 2005-12-25 13:05:07 得分 0

呵呵     面试了十几个公司   至少有90%的公司都出这个题.......Top

30 楼iamcaicainiao(老菜,长征)回复于 2005-12-25 19:27:44 得分 0

以下摘自《林锐-高质量c++c编程指南》-----标准答案  
   
   
  指针参数是如何传递内存的?  
  如果函数的参数是一个指针,不要指望用该指针去申请动态内存。示例7-4-1中,Test函数的语句GetMemory(str,   200)并没有使str获得期望的内存,str依旧是NULL,为什么?  
   
  void   GetMemory(char   *p,   int   num)  
  {  
  p   =   (char   *)malloc(sizeof(char)   *   num);  
  }  
  void   Test(void)  
  {  
  char   *str   =   NULL;  
  GetMemory(str,   100); //   str   仍然为   NULL  
  strcpy(str,   "hello"); //   运行错误  
  }  
  示例7-4-1   试图用指针参数申请动态内存  
   
  毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是   _p,编译器使   _p   =   p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。  
  如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,见示例7-4-2。  
   
  void   GetMemory2(char   **p,   int   num)  
  {  
  *p   =   (char   *)malloc(sizeof(char)   *   num);  
  }  
  void   Test2(void)  
  {  
  char   *str   =   NULL;  
  GetMemory2(&str,   100); //   注意参数是   &str,而不是str  
  strcpy(str,   "hello");  
  cout<<   str   <<   endl;  
  free(str);  
  }  
  示例7-4-2用指向指针的指针申请动态内存  
   
  由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递动态内存。这种方法更加简单,见示例7-4-3。  
   
  char   *GetMemory3(int   num)  
  {  
  char   *p   =   (char   *)malloc(sizeof(char)   *   num);  
  return   p;  
  }  
  void   Test3(void)  
  {  
  char   *str   =   NULL;  
  str   =   GetMemory3(100);  
  strcpy(str,   "hello");  
  cout<<   str   <<   endl;  
  free(str);  
  }  
  示例7-4-3   用函数返回值来传递动态内存  
   
  用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return语句用错了。这里强调不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡,见示例7-4-4。  
   
  char   *GetString(void)  
  {  
  char   p[]   =   "hello   world";  
  return   p; //   编译器将提出警告  
  }  
  void   Test4(void)  
  {  
  char   *str   =   NULL;  
  str   =   GetString(); //   str   的内容是垃圾  
  cout<<   str   <<   endl;  
  }  
  示例7-4-4   return语句返回指向“栈内存”的指针  
   
  用调试器逐步跟踪Test4,发现执行str   =   GetString语句后str不再是NULL指针,但是str的内容不是“hello   world”而是垃圾。  
  如果把示例7-4-4改写成示例7-4-5,会怎么样?  
   
  char   *GetString2(void)  
  {  
  char   *p   =   "hello   world";  
  return   p;  
  }  
  void   Test5(void)  
  {  
  char   *str   =   NULL;  
  str   =   GetString2();  
  cout<<   str   <<   endl;  
  }  
  示例7-4-5   return语句返回常量字符串  
   
  函数Test5运行虽然不会出错,但是函数GetString2的设计概念却是错误的。因为GetString2内的“hello   world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString2,它返回的始终是同一个“只读”的内存块。  
  Top

31 楼youngdreamer2008(羊追馍)回复于 2005-12-25 22:52:28 得分 0

受益匪浅!!!Top

32 楼armman()回复于 2005-12-26 11:14:01 得分 0

各位聪明啊  
  小弟总感觉有点模糊Top

33 楼Mi_Bo(长弓落日)回复于 2005-12-26 12:06:43 得分 0

#include   "stdio.h"  
  #include   <stdlib.h>  
  #include   <string.h>  
  void   GetMemory(char**   p)  
  {  
  *p=(char*)malloc(100);  
  }  
   
  void   main(void)  
  {  
  char   *str=NULL;  
  GetMemory(&str);  
  strcpy(str,"hello   world");  
  printf(str);  
  free(str);  
  }Top

34 楼sky_1982(好好学习)回复于 2005-12-26 13:35:48 得分 0

同感:   snailbreak(南师杀猪的)  
  Top

35 楼pinel()回复于 2005-12-26 13:58:00 得分 0

引用也可以  
   
  #include   "stdio.h"  
  #include   <stdlib.h>  
  #include   <string.h>  
   
  void   GetMemory(char*   &p)  
  {  
          p=(char*)malloc(100);  
  }  
   
  int   main(void)  
  {  
          char   *str=NULL;  
          GetMemory(str);  
          strcpy(str,"hello   world");  
          printf(str);  
          free(str);  
   
          system("PAUSE");  
          return   0;  
  }  
  Top

36 楼kevinlvchina(凯文)回复于 2005-12-26 19:45:45 得分 0

char   *p   =   (char   *)malloc(sizeof(char)   *   num);  
  return   p;  
  如果这样分配的内存就在堆上了,不会随程序消亡而消亡,是这样吗?Top

37 楼benjaming1981(ben)回复于 2005-12-26 20:34:32 得分 0

程序2    
  传递参数时,都是传递副本  
  所以副本指针指向申请的空间  
  原指针仍为空  
   
  不仅没打印出hello   world  
  而且   内存泄漏Top

相关问题

  • 一道笔试题
  • 一道笔试题
  • 一道笔试题
  • 一道笔试题
  • 一道笔试题
  • 一道笔试题
  • 求解一道笔试题
  • 一道笔试题,求解
  • 关于一道笔试题
  • 请问:一道笔试题

关键词

  • c++
  • c++编程
  • 指针
  • 函数
  • 内存
  • 编译器
  • 内存泄漏
  • 乱码
  • getmemory
  • 程序

得分解答快速导航

  • 帖主:goodsun2
  • mccxj

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo