如果想通过函数申请一块内存并将这块内存地址传递出来,需要用到指针的指针,但是在这一块并不是很好理解。虽然不知道自己的想法是不是正确的,但是很好理解,先做一个笔记,免得忘记。
void GetMemory1(char *p,int num)
{
p=malloc(sizeof(int)*num);
return;
}
void Test1()
{
char *p=NULL;
GetMemory(p);
}
比如这个代码,想要在GetMemory1函数中申请内存并由参数p带出来。由于函数的调用会生成参数的副本,即使你将函数参数的值改变,也无法将这个改变的值保持到函数结束后,即调用函数后,这个参数的值本身还是不会发生改变。在GetMemory1函数中,试图修改p的副本_p的值,而不是_p所指向的内存的值,所以p的值实际无法改变。
正确的做法如下:
void GetMemory2(char **p,int num)
{
* p=malloc(sizeof(int)*num);
return;
}
void Test2()
{
char *p=NULL;
GetMemory2(&p);
}
因为我们要将函数中申请的内存传递给指针p,但是我们又不能在函数中直接对p进行内存地址的赋值,那么我们可以通过修改存储指针p的内容来改变指针p所在内存地址的内容来间接改变指针p的值。
p作为一个指针,虽然是用来存储其他变量的内存地址,但是显然,p本身作为一个变量,也是需要内存空间来存储的。比如
int a=5;
int *f=&a;
假设变量a的内存地址为0xa,那么f存储的就是0xa,那么存储f的内存地址呢,那就是&f。
而&f是固定的,那么我们通过直接修改&f所在内存地址,那么f所指向的地址内容就会发生变化。
回到GetMemory2函数,因为p作为一个指针,而对指针取地址符,那么就是指针的指针,所以在函数的参数上面就是char** p,而这里面的p就是GetMemory2(&p)中的&p。
调用我觉得这样写更好理解,或者char* *p,表示指向*p的一个指针。这样的函数调用,实际上就是修改p所在内存空间的值,而不是修改其副本的值。
个人这样理解感觉很简单,虽然不知道正不正确。