C语言中,为什么通过函数为指针变量分配内存,形参一定要是二级指针?

malloc()函数
调用
void get(int **p,int num)
{
*p=(int *)malloc(num*sizeof(int));
return;
}
为什么不能改成
void get(int *p,int num)
..............
请高手指点。。。。。

我感觉没有必要用二级指针,我们的目的主要是为了让主函数中的指针的地址指向一个空内存。我们完全可以通过传递这个指针的地址到子函数中,然后给这个指针的地址分配内存就可以了。例如下面这个程序就是正确的。根本没有必要使用到二级指针呀。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-04-18
假设是这样
void get(int *p,int num)
{
p=(int *)malloc(num*sizeof(int));
return;
}

调用函数
int *pi;
get(pi,10); get函数里的这个参数只是pi的一个副本,get函数结束后就没了,malloc分配的内存首地址也没带出来,pi还是原来的pi没变,还发生了内存泄漏

想用一级指针当参数 可以这样
int* get(int *p,int num) //返回指针
{
p=(int *)malloc(num*sizeof(int));
return p;
}
这样看起来是返回了一个局部变量的地址,但这个地址是个堆地址,函数结束后任然有效,只要记得释放就行了

那么就可以这样了

int* pi;

pi=get(pi, 10); //是不是有点脱裤放屁的感觉,还不如直接pi=(int*)malloc(10*sizeof(int))

最后在适当的时候释放 free(pi)
第2个回答  推荐于2018-04-14
这其实就是参数传递的一个问题,我只能说通过一个简单的例子来类比。
先说一个简单点的问题:如果说我想通过参数来改变一个整数类型的变量的值,就只能用
void Fun(int *a)
{
*a=9;
}
而不能用
void Fun(int a)
{
a=9;
}
因为我的第一种写法传入的是变量a在内在中的地址,子函数改变的是这个地址所指向的内存空间里面的内容,从而改变了变量的值;但是第二种写法只是将变量a的值传入到函数当中,并不能改变它的值。你说的情况跟这个是类似的,第二种情况没有改变p的值(p的值是一个地址,函数执行完之后p的值没变,所以还是指向原来的内存空间)本回答被提问者和网友采纳
第3个回答  2012-04-18
函数调用其实就是值传递
#include <iostream>
using namespace std;

void get(int *p)
{
*p=5;
}
void main()
{
int i=1;
int *p1=&i;
cout<<i<<endl;
get(p1);
cout<<i<<endl;
}
为什么我们用指针可以 i 的值,其实就是把 i 的地址值p1(&i)传递到p中,这是*p(*(&i))还不是指的 i ;
我们再看下面两个方法,这里我们的目的为*p1分配内存,也就是改变p1的值。
void get(int **p,int num);
void get(int *p,int num);
int *p1,i=1;
get(p1,i); //p1的值(unsigned int)传递给p,现在执行*p=(int *)malloc(num*sizeof(int));这时改变的是*p1,然而p1没变
get(&p1,i); //p1的 地址值 (unsigned int)传递给p,现在执行*p=(int *)malloc(num*sizeof(int));这时改变的就是p1

推荐你看看内存管理 http://www.cppblog.com/yishanhante/articles/18957.html?opt=admin
第4个回答  2012-04-18
可以改,但你下面也要改
*p=(int *)malloc(num*sizeof(int));
改成
p=(int *)malloc(num*sizeof(int));追问

这么改不行。。。。书上说,像你那样改出现野指针!书上明确指出通过函数给指针变量分配内存,必须用二级指针。。。。。我想知道必须这么干的理由。。。

追答

书是死的,人是活的,书上的不是完全对的。主要看你用什么编程工具,要是你用的是VC6.0我没活说。不过还有一个问题,在你函数return前要free掉p。否则就真有问题,不过如果不是大型程序,问题也不大,只是暂时的内存泄漏。就算你使用了二级指针free这个动作也是有必要的。

相似回答