本文是在编程过程中遇到的实际问题,作为总结。参考文档:http://blog.csdn.net/gexueyuan/article/details/9077679
一般用指针做函数形参是为了传入参数地址,来进行修改实参数的值,即指针指向的值。但是如果要用来修改指针本身的值则需要指针的指针或者指针变量的传址引用。
先来看一段经典的代码:
void GetMemory1( char *p )
{
p = (char *) malloc( 100 );
}
void Test( void )
{
char *str = NULL;
GetMemory1( str );
strcpy( str, "hello world" );
printf( str );
}
显然你会发现,经过指针变量通过函数Getmemory后,还是null,并没有分配内存,所以编译运行会出错,或者直接编译报错。 原因在于,函数参数传递的时候,直接传递是值传递,需要引用传递需要加上‘&’,作为值传递,p=str,也就是说,p指向的地址和str指向的地址是相同的,同为指向null,但是在函数中局部变量p又重新分配了100个字节的变量,他的值发生变化,指向了别的地址,但是str并没有变化,所以函数对str是无效的。
究其根本原因,在于p指针的地址和str指针的地址不一样,两者只是共同指向同一个地方(p先指向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 );
}
GetMemory2函数还可以使用数组指针进行传值,如GetMemory2(char* p[], int num);
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 );
}
该方法使用一个指针函数,返回一个指向分配好内存的地址,返回的是一个值(p指向的地址,一个int变量(处理器位数决定)),是能够返回的,如果返回的是指向局部变量的指针,那么会发生程序错误。指针做函数返回值,指向的值在函数结束后不能够被注销,否则发生程序错误(返回时并没有错,使用的时候已经变成未知的值,可能造成系统紊乱)。