问题描述
#include <stdlib.h>
int malloc2(int **a) {
*a = malloc(sizeof (int));
return 0;
}
int main() {
int* b = NULL;
malloc2(&b);
}
如果一个参数只接受双指针,它如何接受地址值?
解决方法
如果不通过指向它的指针通过引用传递指针b
,则该函数将处理指针值的副本
在函数内更改副本不会影响原始指针。
结果是该函数产生了内存泄漏。
要更改原始指针 b
,该函数需要直接访问该指针。可以通过解引用指向指针(对象)b
的指针来实现。
比较这两个演示程序。
#include <stdio.h>
void f( int *p )
{
++p;
printf( "Within the function f p = %p\n",( void * )p );
}
int main(void)
{
int x = 10;
int *p = &x;
printf( "Before calling f p = %p\n",( void * )p );
f( p );
printf( "After calling f p = %p\n",( void * )p );
return 0;
}
程序输出为
Before calling f p = 0x7ffc3a940cbc
Within the function f p = 0x7ffc3a940cc0
After calling f p = 0x7ffc3a940cbc
如您所见,在调用函数 p
后,main 中声明的指针 f
没有改变。
另一个程序
#include <stdio.h>
void f( int **p )
{
++*p;
printf( "Within the function f p = %p\n",( void * )p );
f( &p );
printf( "After calling f p = %p\n",( void * )p );
return 0;
}
程序输出为
Before calling f p = 0x7ffe011131ec
Within the function f p = 0x7ffe011131f0
After calling f p = 0x7ffe011131f0
现在可以看到 main 中声明的指针 p
在调用函数 f
后发生了变化,因为它是通过指向它的指针通过引用传递给函数的。取消对指针的引用,函数可以直接访问在 main 中声明的指针 p
。
如果一个参数只接受双指针,它怎么能接受一个 地址值
每个值都根据其类型进行解释。此表达式 &b
的值具有类型 int **
。并且函数参数也有 int **
类型。
您可以想象函数定义及其调用方式如下
int main() {
int* b = NULL;
malloc2(&b);
}
//...
int malloc2( /* int **a */ ) {
int **a = &b;
*a = malloc(sizeof (int));
return 0;
}
即函数参数a
由表达式&b
的值初始化。
或者更简单的例子
int main( void )
{
int x = 10;
int *b = &x;
int **a = &b;
}
,
该函数接受单个 int **
参数,即 pointer-to-pointer-to-int。
b
中的变量 main
的类型为 int *
,即 pointer-to-int。如果你然后取 b
的地址,你现在有一个 pointer-to-pointer-to-int,即匹配函数参数的 int **
。