指针参数的传递(节选 C++/C 高质量编程 林锐)
指针参数是如何传递内存的
如果函数的参数是一个指针,不要指望用该指针去申请动态内存。示例7-4-1中,Test函数的语句GetMemory(str, 200)并没有使str获得期望的内存,str依旧是NULL,为什么?
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"); // 运行错误 } |
示例7-4-1 试图用指针参数申请动态内存
毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。
如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,见示例7-4-2。
void GetMemory2(char **p, int num) { *p = (char *)malloc(sizeof(char) * num); } |
void Test2(void) { char *str = NULL; GetMemory2(&str, 100); // 注意参数是 &str,而不是str strcpy(str, "hello"); cout<< str << endl; free(str); } |
示例7-4-2用指向指针的指针申请动态内存
由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递动态内存。这种方法更加简单,见示例7-4-3。
char *GetMemory3(int num) { char *p = (char *)malloc(sizeof(char) * num); return p; } |
void Test3(void) { char *str = NULL; str = GetMemory3(100); strcpy(str, "hello"); cout<< str << endl; free(str); } |
示例7-4-3 用函数返回值来传递动态内存
用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return语句用错了。这里强调不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡,见示例7-4-4。
char *GetString(void) { char p[] = "hello world"; return p; // 编译器将提出警告 } |
void Test4(void) { char *str = NULL; str = GetString(); // str 的内容是垃圾 cout<< str << endl; } |
示例7-4-4 return语句返回指向“栈内存”的指针
用调试器逐步跟踪Test4,发现执行str = GetString语句后str不再是NULL指针,但是str的内容不是“hello world”而是垃圾。
如果把示例7-4-4改写成示例7-4-5,会怎么样?
char *GetString2(void) { char *p = "hello world"; return p; } |
void Test5(void) { char *str = NULL; str = GetString2(); cout<< str << endl; } |
示例7-4-5 return语句返回常量字符串
函数Test5运行虽然不会出错,但是函数GetString2的设计概念却是错误的。因为GetString2内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString2,它返回的始终是同一个“只读”的内存块。
指针参数的传递(节选 C++/C 高质量编程 林锐)的更多相关文章
- C++/C高质量编程指南-笔记
复习: C/C++高质量编程指南: [规则1-2-1]为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块. [规则1-2-2]用 #include <file ...
- c++高质量编程手册
怡化主管强烈要求我读这本书.... 笔记尚未完成,持续更新呗.. 第1章 高质量软件开发之道 1.1 软件质量基本概念 1.1.1 如何理解软件的质量:功能性和非公能性 1.1.2 提高软件质量的基本 ...
- C++高质量编程笔记
/* * 函数介绍: * 输入参数: * 输出参数: * 返回值 : */ void Function(float x, float y, float z) { - } if (-) { - whil ...
- C++ 高质量编程附录试题
附录B :C++/C试题 本试题仅用于考查C++/C程序员的基本编程技能.内容限于C++/C常用语法,不涉及数据结构.算法以及深奥的语法.考试成绩能反映出考生的编程质量以及对C++/C的理解程度,但不 ...
- C++函数的重载,覆盖和隐藏(——高质量编程第14章)
函数重载概念 只有C++才有重载的概念,C语言没有. 靠行参列表的不同来区别不同的重载函数, 若是全局函数和成员函数同名时,不算重载,因为它们的作用域不同,所以成员函数会将全局函数给隐藏(遮蔽)了 ...
- 【c++】指针参数是如何传递内存的
[c++]指针参数是如何传递内存的 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *) ...
- 【转】【c++】指针参数是如何传递内存的
参数策略 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(c ...
- C++指针作为函数的参数进行传递时注意的问题
应注意问题: 当指针作为函数的参数进行传递的时候,本质上还是进行的"值传递",也就是复制了一个新的指向该地址的指针变量. 只有在被调函数中,对指针进行引用操作,才可以达到不需要返回 ...
- c++指针参数是如何传递内存的
参数策略 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(c ...
随机推荐
- 基尔霍夫矩阵题目泛做(AD第二轮)
题目1: SPOJ 2832 题目大意: 求一个矩阵行列式模一个数P后的值.p不一定是质数. 算法讨论: 因为有除法而且p不一定是质数,不一定有逆元,所以我们用辗转相除法. #include < ...
- 练习—单链表—Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2-& ...
- OpenCV——手势识别
使用ANN神经网络训练数据后进行手势识别. #include "header.h" int main() { ; //训练每类图片数量 ; //训练类数3:石头剪刀布 ; ; st ...
- javascript的全局变量
javascipt是一门面向对象的编程语言.由于存在一些全局属性及全局函数,因此可以认为存在一个全局变量,这些全局属性及全局函数均是其属性或函数. 在js核心中,并没有定义一个具体的全局变量,因此,j ...
- js prototype之诡异
想必经常写js的人必然会经常性的用到prototype这个属性,我写这篇文章倒不是自己对prototype这个属性理解有多深刻,相反是因为自己理解肤浅,想通过写文章来加深理解.废话不多说.下面总结一下 ...
- css 完美替换图片
1.css替换简单图标的展示方法 ;display:inline-block;position:absolute;left:11px;top:10px;border-right:6px solid t ...
- hdu 4419 Colourful Rectangle
http://acm.hdu.edu.cn/showproblem.php?pid=4419 题意:给出3种颜色,重叠会生成新的颜色,然后有一些矩形,求出每种颜色的面积. 转化为二进制表示颜色:001 ...
- hdu 1595 find the longest of the shortest
http://acm.hdu.edu.cn/showproblem.php?pid=1595 这道题我用spfa在枚举删除边的时候求最短路超时,改用dijkstra就过了. #include < ...
- SDL入门教程(一):3、MinGW 下的安装与设置
作者:龙飞 3.1:MinGW 是什么? MinGW 提供了一套简单方便的Windows下的基于GCC 程序开发环境.MinGW 收集了一系列免费的Windows 使用的头文件和库文件:同时整合了GN ...
- ScrollView中添加ListView
<p>.要点一:去除ListView的scrollBar,添加ScrollView的scrollBar:</p> <ScrollView android:layout_w ...