您的位置:首页 > 编程语言 > C语言/C++

提高C++代码质量 - [085]了解指针参数传递内存中的玄机

2015-03-03 15:51 381 查看
概述:用指针参数传回一块动态申请的内存,是很常见的一种需求。但是若不小心,就会造成程序崩溃+内存泄漏!解决之道就是用指针的指针来传递,或者换一种内存传递方式,比如用返回值来传递。



用指针参数传递函数内部动态申请的内存,这是一个比较容易出错的知识点,也是各家IT公司面试时出现频率极高的笔试题目之一。如下代码:

void GetMemory1(char* pStr, int num)

{

pStr = new char[num];

}



int main()

{

char* strHello = NULL;

GetMemory1(strHello, 100);

strcpy(strHello, “Hello C++ Tips”);

delete[] strHello;

return 0;

}

看起来没什么问题,但是运行程序是,程序出错了:

0xC0000005:写入位置0x00000000时发生访问冲突

哪里出了问题呢?

针对函数的每个参数,编译器都要为其生成一个临时副本,指针参数pStr的副本是_pStr,并且会使_pStr = pStr = 0x00000000。在函数体内通过new修改了_pStr的值,使之指向一块已申请的内存,而pStr却没有改变,仍然是0x00000000。所以GetMemory1并没有通过指针参数返回一个有效的内存地址,并且,每被调用一次,就会造成一块内存的泄露。

如果非得要用指针参数去申请内存,那么就应该改用“指向指针的指针”,代码修改如下:

void GetMemory2(char** p, int num)

{

*p = new char[num];

}



int main()

{

char* strHello = NULL;

GetMemory2(&strHello, 100);

strcpy(strHello, “Hello C++ Tips”);

delete[] strHello;

return 0;

}

OK,目标达成!

其实最容易的方法还是用返回值来传递动态内存,代码如下:

class* GetMemory3(int num)

{

char* p = new char[num];

return p;

}


这里需要特别强调的是,不要用return返回指向“栈”内存的指针,因为该内存在函数结束时会自动消亡。

现在将这个话题扩展开来,如果想在函数内部对传入参数的值进行修改,那么单纯的传入这个参数是绝对不行的,需要传入的必须是欲该变量的指针。举例来说,如果参数本身是int 那么传入的类型应该是int* ;如果参数本身是float 那么传入的类型应该是float*

请记住:
用指针系数传回一个动态申请的内存,是很常见的一种需求,然而如果不甚小心,就很容易造成严重错误:程序崩溃和内存泄露,解决之道就是用指针的指针来传递 或者用返回值来传递
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: