C内存之指针传递

众所周知,C语言中有两种函数参数传递方式:值传递和地址传递。
指针常用来分配空间,其意义是指向一个有意义的地址。我们也通常用指针做参数来进行地址传递。
However,指针做参数都是地址传递吗?

请大家先看这样的一段程序:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void test(char*p)
{
     p = (char*)malloc(sizeof (char) * 10);
}

int main()
{
     char *ts = NULL;

     test(ts);
     strcpy(ts, "Succeed !");
     puts(ts);

     return 0;
}

 

以上程序当然是错误的:
1.不能达到为ts分配内存的目的。
2.造成内存泄露。

究其原因:错把test函数的参数传递当成了地址传递。
其实,真相是这样的:
1.栈上分配4字节给了ts,将其指向空地址。
2.调用test函数,将ts作为实参传递给形参p,即将test中的参数副本_p指向空地址。这其实是“值传递”,ts的值(即空地址)传递给了形参p,ts和p指向同一地址。
3.在堆上开辟一段空间,并将p的值修改为当前开辟空间的首地址。由值传递的单向性可知,ts本身的值并未改变,仍为空地址。故在strcpy()时出错。

知道了出错的原因,我们就能对其进行改正。

改正1.

可以改变ts指向,将其与p指向同一块地址。利用函数的返回值。
char* test(char*p)
{
    p = (char*)malloc(sizeof (char) * 10);
   
    return p;                                          // 切记:别返回栈内指针。
}

那么在main函数中调用test函数时:

改正2.

改变ts自身地址。这一招真绝。使用双重指针。

void test(char**p)
{
    *p = (char*)malloc(sizeof (char) * 10);
}

main函数中就这样调用test:

test(&ts);                            // 这传的才是ts自己的地址,而不是其保存的内容。地址传递。
free(ts);

 

posted @ 2013-11-13 18:48  KingDr  阅读(368)  评论(0编辑  收藏  举报