内存操作 / 野指针

试题 4 : 

void GetMemory( char *p ) 
{ 
   p = (char *) malloc( 100 ); 
} 

void Test( void ) 
{ 
   char *str = NULL; 

   GetMemory( str ); 
   strcpy( str, "hello world" ); 
   printf( str ); 
} 
试题 5 : 

char *GetMemory( void ) 
{    
     char p[] = "hello world";       

     return p;   
} 
void Test( void ) 
{    
     char *str = NULL;   

     str = GetMemory();    
     printf( str );    
} 

试题 6 : 
void GetMemory( char **p, int num ) 
{ 
     *p = (char *) malloc( num ); 
} 
void Test( void ) 
{ 
     char *str = NULL; 

     GetMemory( &str, 100 ); 
     strcpy( str, "hello" ); 
     printf( str ); 
} 

试题 7 : 

void Test( void ) 
{ 
     char *str = (char *) malloc( 100 ); 

     strcpy( str, "hello" ); 
     free( str ); 

     ...  // 
省略的其它语句 

} 

解答: 

试题 4 传入中 GetMemory( char *p ) 函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完 

char *str = NULL; 

GetMemory( str ); 

后的 str 仍然为 NULL ; 

试题 5 中 

     char p[] = "hello world";    

     return p;   

的 p[] 数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。 
试题 6 的 GetMemory 避免了试题 4 的问题,传入 GetMemory 的参数为字符串指针的指针,但是在 GetMemory 中执行申请内存及赋值语句 

p = (char *) malloc( num ); 

后未判断内存是否申请成功,应加上: 

if ( p == NULL ) 
{ 

   ...// 
进行申请内存失败处理 
  } 

试题 7 存在与试题 6 同样的问题,在执行 

char *str = (char *) malloc(100); 

后未进行内存是否申请成功的判断;另外,在 free(str) 后未置 str 为空,导致可能变成一个  野  指针,应加上: 

str = NULL; 

试题 6 的 Test 函数中也未对 malloc 的内存进行释放。 

剖析: 

试题 4 ~ 7 考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中 50~60 的错误。但是要完全解答正确,却也绝非易事。 

对内存操作的考查主要集中在: 

( 1 )指针的理解; 

( 2 )变量的生存期及作用范围; 

( 3 )良好的动态内存申请和释放习惯。 

在看看下面的一段程序有什么错误: 

swap( int* p1,int* p2 ) 
{ 
     int *p; 

     *p = *p1; 
     *p1 = *p2; 
     *p2 = *p; 
} 

在 swap 函数中, p 是一个  野  指针,有可能指向系统区,导致程序运行的崩溃。在 VC++ 中 DEBUG 运行时提示错误 “Access Violation” 。该程序应该改为: 

swap( int* p1,int* p2 ) 
{ 
     int p; 

     p = *p1; 
     *p1 = *p2; 
     *p2 = p; 

转自:http://www.cppblog.com/qiaodong/archive/2006/11/09/14905.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值