首页 > C > 指针 阅读:57,774

指针做实参,如何修改指针

指针做实参,如果想修改指针的值,必须传指针的指针或者指针的引用。现在来分析下面的C代码:

void GetMemory(char *p)

{

    p = (char *)malloc(100);

}

void Test(void)

{

    char *str = NULL;

    GetMemory(str);

    strcpy_s(str, 100,"hello world");

    printf(str);

    free(str);

    str=NULL;

}

 

请问运行Test 函数会有什么样的结果?

分析:上面的代码试图使用指针作为参数,分配动态内存。该代码会存在两个问题:

1.  内存泄漏。

首先,通过指针作为参数无法成功申请一块动态分配的内存。这是因为,GetMemory()函数获得的是实参指针变量的一个拷贝。因此,它只是将新分配的内存赋给了形参(即实参指针的拷贝)。而实参并没有获得这块内存。在Test()函数中,发现并没有释放str指向内存的语句。但这不是内存泄露的根本原因。即使在程序后面加上一句:

free(str);

内存依然会泄漏。这是因为,str根本没有获得这块内存,而是由形参获得了。而形参是一个栈上的变量。在函数执行之后就已经被系统收回了。这是造成了内存泄漏的根本原因。

要想成功获得分配的内存,可以采用下面的两种方法:

 

char* GetMemory(char *p)

{

     p = (char *)malloc(100);

     return p;

}

 

上面的代码直接返回新分配的内存。由于内存是在堆上而不是在栈上分配的,所以函数返回后不存在任何问题。

或者:

 

void GetMemory(char **p)//传指针的指针

{

    *p = (char *)malloc(100);

}

void Test(void)

{

    char *str = NULL;

    GetMemory(&str);

    strcpy_s(str, 100,"hello world");

    printf(str);

    free(str);

    str=NULL;

}

这种方法是通过指针的指针来分配内存。用这种方法分配内存,传递给函数的是指针地址的一个拷贝,那么*p就是指针本身。因此新分配的内存成功的赋给了做实参的指针。

void GetMemory(char *&p)//传指针的引用(引用是C++中的概念)

{

    *p = (char *)malloc(100);

}

void Test(void)

{

    char *str = NULL;

    GetMemory(str);//传指针的引用

    strcpy_s(str, 100,"hello world");

    printf(str);

    free(str);

    str=NULL;

}

2.  NULL指针引用导致程序崩溃。

由于str并没有获得这块内存,那么str的值依然为NULL,所以strcpy()函数访问了一个NULL指针,直接导致程序崩溃。

周哥教IT,分享编程知识,提高编程技能,程序员的充电站。跟着周哥一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

当你决定关注「周哥教IT」,你已然超越了90%的程序员!

IT黄埔-周哥教IT技术交流QQ群:213774841,期待您的加入!

二维码
微信扫描二维码关注