指针参数是如何传递内存的

如果函数的参数是一个指针,不要指望用该指针去申请动态内存。示例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 高质量编程 林锐)的更多相关文章

  1. C++/C高质量编程指南-笔记

    复习: C/C++高质量编程指南: [规则1-2-1]为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块. [规则1-2-2]用 #include <file ...

  2. c++高质量编程手册

    怡化主管强烈要求我读这本书.... 笔记尚未完成,持续更新呗.. 第1章 高质量软件开发之道 1.1 软件质量基本概念 1.1.1 如何理解软件的质量:功能性和非公能性 1.1.2 提高软件质量的基本 ...

  3. C++高质量编程笔记

    /* * 函数介绍: * 输入参数: * 输出参数: * 返回值 : */ void Function(float x, float y, float z) { - } if (-) { - whil ...

  4. C++ 高质量编程附录试题

    附录B :C++/C试题 本试题仅用于考查C++/C程序员的基本编程技能.内容限于C++/C常用语法,不涉及数据结构.算法以及深奥的语法.考试成绩能反映出考生的编程质量以及对C++/C的理解程度,但不 ...

  5. C++函数的重载,覆盖和隐藏(——高质量编程第14章)

      函数重载概念 只有C++才有重载的概念,C语言没有. 靠行参列表的不同来区别不同的重载函数, 若是全局函数和成员函数同名时,不算重载,因为它们的作用域不同,所以成员函数会将全局函数给隐藏(遮蔽)了 ...

  6. 【c++】指针参数是如何传递内存的

    [c++]指针参数是如何传递内存的   如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *) ...

  7. 【转】【c++】指针参数是如何传递内存的

    参数策略 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(c ...

  8. C++指针作为函数的参数进行传递时注意的问题

    应注意问题: 当指针作为函数的参数进行传递的时候,本质上还是进行的"值传递",也就是复制了一个新的指向该地址的指针变量. 只有在被调函数中,对指针进行引用操作,才可以达到不需要返回 ...

  9. c++指针参数是如何传递内存的

    参数策略 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(c ...

随机推荐

  1. POJ 1001 Exponentiation 模拟小数幂

    模拟小数幂 小数点位 pos 非零末位 e 长度 len 只有三种情况 pos > len pos < e e < pos < len #include <iostrea ...

  2. WordPress插件制作教程(八): 最后总结

    WordPress插件教程最后一篇,还是为大家简单的做下总结.这次插件制作教程讲的内容和知识点个人觉得不是很多,因为插件制作不单单是这些内容,它涉及的知识很多很多,不是说你会一些函数就可以做出一个好的 ...

  3. Virtual Box 工具栏(菜单栏)消失的解决方法

    异常处理汇总-开发工具  http://www.cnblogs.com/dunitian/p/4522988.html 现在Virtual Box非常牛逼(不排除Oracle又准备像Java SE那样 ...

  4. bootstrap 模态框动态加载数据

    .页面中添加modal <!-- 模态框(Modal) --> <div class="modal fade" id="showModal" ...

  5. 关于BitmapFactory.decodeStream(is)方法无法正常解码为Bitmap对象的解决方法

    在android sdk 1.6版本API帮助文档中,其中关于BitmapFactory.decodeFactory.decodeStream(InputStream is)的帮助文档是这么说明的: ...

  6. Android得到控件在屏幕中的坐标

    getLocationOnScreen ,计算该视图在全局坐标系中的x,y值,(注意这个值是要从屏幕顶端算起,也就是索包括了通知栏的高度)//获取在当前屏幕内的绝对坐标 getLocationInWi ...

  7. rsyslog 收集系统日志

    <pre name="code" class="html">nginx 服务器配置: jrhwpt01:/root# cat /etc/rsyslo ...

  8. SQL省市区三级表结构

    -- 表的结构 areaDROP TABLE  area;CREATE TABLE  area (   id int NOT NULL ,  areaID int NOT NULL,  area va ...

  9. 需要考虑的9个SEO实践

    搜索引擎优化重要吗?我们知道,网站设计是把屏幕上平淡无奇变成令人愉快的美感,更直观地辨认信息.这也是人与人之间在沟通想法,这样的方式一直在演变. 穴居人拥有洞穴壁画,古埃及人有象形文字,现代人有网页设 ...

  10. Linux中使用mysqldump对MySQL数据库进行定时备份

    #!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH expo ...