指针传递内存的做法

1、如果函数的参数是一个指针,不要用该指针去申请动态内存。示例如下

void GetMemory(char *p, int num)

{

p = (char *)malloc(sizeof(char)*num);

}

void Test(void)

{

char *str = NULL;

GetMemory(str, 100); //str仍然为NULL

strcpy(str,"hello");  //运行时错误

}

问题:对于函数GetMemory(),编译器总要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p = p。如果函数体内的程序修改了_p指向的内容,就导致参数p指向的内容也被做了相应的修改,这就是指针可以用做输出参数的原因。但本例中,_p申请了新的内存,只是把_p本身的值改变了,即指向了新的内存空间,但是p本身丝毫没变(即修改了_p本身的值,而不是_p指向的对象)。所以函数GetMemory()并不能输出任何东西,每执行一次GetMemory()就会泄漏一块内存。

2、应使用“指向指针的指针”或者“指向指针的引用”去申请内存

void GetMemory(char **p, int num)   //或者是char *&rp

{

*p = (char *)malloc(sizeof(char)*num);   //rp = ...

}

void Test(void)

{

char *str = NULL;

GetMemory(&str, 100); //注意参数时&str,而不是str

strcpy(str,"hello"); //OK

cout<<str<<endl;  

free(str);  //ok

}

3、“指向指针的指针”与“指针的引用”不容易理解,可以用函数返回值来传递动态内存,示例如下:

char * GetMemory(int num)

{

char *p = (char *) malloc(sizeof(char)*num);

return p;

}

void Test(void)

{

char *str = NULL;

str = GetMemory(100);

strcpy(str,"hello");

cout<<str<<endl;

free(str);

}

注意:不要用return语句返回指向“栈内存”的指针或引用,因为该内存在函数结束时将自动释放,示例如下:

char *GetString(void)

{

char p[] = "hello world";   //用字符串常量初始化数组的内存空间

return p;   //编译器将提出警告

}

void test(void)

{

char *str = NULL;

str = GetString();  //str 的内容是垃圾

cout<<str<<endl

}

但上例修改成指针指向常量字符串的形式,则字符串位于静态存储区,在程序生命周期内始终有效,返回的始终是同一个“只读”内存块的地址,不可试图对它进行写操作,可以把返回值改为const char* 以避免无意中的修改。示例:

char * GetString2(void)

{

char *p = "hello world";

return p;

}

void Test(void)

{

char *str = NULL;

str = GetString2();

cout<<str<<endl;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值