指针作为函数的参数,则不能用此申请内存

来源:互联网 发布:zwift 软件下载 编辑:程序博客网 时间:2024/05/17 22:31

今天读到林悦的一句话:如果函数是一个指针则不要指望使用该指针申请动态内存,找了几个例子方便理解:

    void GetMemory1( char *p )      {          p = (char *) malloc( 100 );      }            void Test( void )      {          char *str = NULL;          GetMemory1( str );          strcpy( str, "hello world" );          printf( str );      }  
上面的例子中意思是想通过 GetMemory1函数来给str申请动态内存,但是在实际运行的时候,一般编译器都会报错,因为没有申请成功。

深入理解一下为什么会变异失败:

首先需要明确一点的是值传递和引用传递,其中值传递分为数值传递和指针传递,也就是说指针传递其实也是一次赋值,拷贝的过程。

拿例子中的Test函数来说,当调用到GdtMemory函数的时候其实就是经历了一次赋值的过程:

char *p=str

也就是p和str都指向了空,如下图所示:



此时在GetMemory函数中,给P申请了新的空间,此时P指向了一个新的地址,但是str的指向地址没有变化,还是NULL。如下图所示:


此时str是空,给其赋值,肯定会出现问题。简单来说:

要在函数内部改变某个变量的值,使之能在出了这个函数后,刚才的改变仍然有效,那就必须通过参数传入“指向这个变量的指针”,而不是变量本身。也就是说,任何函数都不能把对参数本身的改变带到函数体外,所改的只是这个参数所指向的变量的值。

如果想要达到在调用函数中分配内存的效果,有以下两种方法:

1.双重指针

    void GetMemory2(char **p, int num)       {           *p = (char *)malloc(sizeof(char) * num);           if ( *p == NULL )          {           printf("Malloc error!\n");        }       }       void Test(void)      {           char *str=NULL;           GetMemory2(&str, 100);           strcpy(str,"hello world");           printf(str);           free( str );       }  
2.参数返回指针申请好的空间

    char *GetMemory3()      {            char *p=(char *)malloc(100);            if ( *p == NULL )           {               printf("Malloc error!\n");                 return NULL;          }            return p;       }       void Test(void)    {           char *str=NULL;           str=GetMemory3();          strcpy(str,"hello world");           printf(str);           free( str );       }  




原创粉丝点击