如何正确为函数参数中的指针动态分配内存

来源:互联网 发布:php 图文直播系统 编辑:程序博客网 时间:2024/06/11 21:03

这里先介绍一种常见的错误分配方法:

void GetMemory(char *p)

{

       p = (char *)malloc(num);

}

void FreeMemorry(char *p)
{
    p = NULL;
    free(p);
}

int main()
{
    char *str = NULL;
    GetMemorry(str,10);
    strcpy(str,"hello");
    printf("%s\n",str);
    FreeMemorry(str);
    return 0;
}

运行程序后,发现出错,错误原因是什么呢?调试发现,str的地址值一直是"0x00000000",并没有真正赋予内存空间,也即实参未被改变,有人说函数是传了地址啊,怎么会没改变实参,其实这里传递地址是没错.但要清楚函数传参方式中传值和传址的原理其实是一样的,都是将实参的拷贝赋给形参,这里将str(str代表一个地址)的拷贝(这个地址值假设为q)赋给形参(指针p),执行  p = (char *)malloc(num)后,将分配内存的首地址赋给q(即q的值改变了,它的值即是刚分配内存的地址),而str并没有获得分配内存的地址.所以str的地址值一直是"0x00000000".

知道了错误的原因,我们就可以使用正确的方法了,如下:

*void GetMemorry(char **p,int num)
{
    *p = (char *)malloc(num);
}
void FreeMemorry(char **p)
{
    *p = NULL;
    free(*p);
}

int main()
{
    char *str = NULL;
    GetMemorry(&str,10);
    strcpy(str,"hello");
    printf("%s\n",str);
    FreeMemorry(&str);
    return 0;
}

运行后正确,这里为啥正确呢?原因很简单,虽然传递的还是一个指针,但这个指针和上面的不一样,执行函数时,依然是将str的地址的拷贝赋值给形参**p,我们知道**p是指针的指针,即它存储的值还是一个地址,执行*p = (char *)malloc(num)后,*p被赋值新分配内存的地址,它的值改变了,且str的值也改变了,为什么?因为改变的是同一个地址值中的内容,这里的地址值即是str的地址(也是p的值),地址值中的内容是str的值(也是*p的值).所以当将分配的内存地址赋给*p时,实际上就是将分配的内存地址赋给str.即str被正确分配内存.