C语言传值操作


    C语言中的函数参数传递都是传值操作,所以要使被调用函数改变调用函数的属性内容,则需要传递所需修改属性的指针——属性地址。

   例1:

C代码
  1. void  GetMemory( char  *p)  
  2. {  
  3.     p = (char  *)malloc(100);  
  4. }  
  5.   
  6. void  Test( void )  
  7. {  
  8.     char  *str = NULL;  
  9.     GetMemory(str);   
  10.     strcpy(str, "hello world" );  
  11.     printf(str);  
  12. }  

 

    请问运行Test 函数会有什么样的结果?

    答: 因为GetMemory函数接收的是str指针的拷贝 ,所以,当其退出时,str的拷贝p在栈中的内容会被释放,并且以上操作对Test 函数中的str没有影响, str一直都是 NULL strcpy(str, "hello world"); 将使 程序崩溃。

 
   例2:
C代码
  1. Void GetMemory2( char  **p,  int  num)  
  2. {  
  3.     *p = (char  *)malloc(num);  
  4. }  
  5.   
  6. void  Test( void )  
  7. {  
  8.     char  *str = NULL;  
  9.     GetMemory(&str, 100);  
  10.     strcpy(str, "hello" );    
  11.     printf(str);     
  12. }  
 

    请问运行Test 函数会有什么样的结果?

    答: 1 )能够输出hello; 2 )内存泄漏

     原因:以上两个对照说明形参只能传递地址不能传递值。

  例3:

C代码
  1. char  *GetMemory( void )  
  2. {    
  3.     char  p[] =  "hello world" ;   //此行将p[]改成*p就对了,此时p[]存在   
  4.     return  p;                          //于栈里边,*p的话字符串存于常量区   
  5. }  
  6.   
  7. void  Test( void )  
  8. {  
  9.     char  *str = NULL;  
  10.     str = GetMemory();  
  11.     printf(str);  
  12. }  

 

请问运行Test 函数会有什么样的结果?

 

    请问运行Test 函数会有什么样的结果?

    答: 可能是乱码。 因为GetMemory 返回的是指向“栈内存”的指针,该指针的地址不是 NULL ,但其原现的内容已经被清除,新内容不可知。

  例4:

C代码
  1. void  Test( void )  
  2. {  
  3.     char  *str = ( char  *) malloc(100);  
  4.     strcpy(str, “hello”);  
  5.     free(str);  
  6.     if (str != NULL)  
  7.     {  
  8.       strcpy(str, “world”);  
  9.       printf(str);  
  10.      }  
  11. }  
 

   答:篡改动态内存区的内容,后果难以预料,非常危险。

   因为free(str); 之后,str 成为野指针,

   if(str != NULL) 语句不起作用。谨记malloc之后一定记得free,free之后将指针NULL一下,以免形成野指针。
 
  以下摘自其他地方:
 例5:
C代码
  1. void  GetMemory( char  **p, int  num)  
  2. {   
  3.     /*p,指向指针的指针,*p,p指向的指针(即str),**p,最终的对象,str指向的单元*/   
  4.   *p=(char  *)malloc(num);    
  5.     //申请空间首地址付给传入的被p指向的指针,即str   
  6. }    
  7.     
  8. int  main()  
  9. {  
  10.          char  *str=NULL;  
  11.    GetMemory(&str,100);   //传入指针变量本身的地址   
  12.    strcpy(str,"hello" );  
  13.    free(str);  
  14.    if (str!=NULL)  
  15.    {  
  16.       strcpy(str,"world" );  
  17.    }         
  18.    printf("/n str is %s" ,str); 软件开发网 www.mscto.com  
  19.    getchar();  
  20. }    
 
  问输出结果是什么?
  
   答案:输出str is world。
  free 只是释放的str指向的内存空间,它本身的值还是存在的.所以free之后,有一个好的习惯就是将str=NULL.此时str指向空间的内存已被回收, 如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚 了),但是通常会打印出world来。这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。当你malloc一块内存的时候, 管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存 前面一点),并将可用内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的。

 

转载自:[http://lhg803.javaeye.com/blog/417858]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值