参数策略

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

  1. void GetMemory(char *p, int num)
  2. {
  3. p = (char *)malloc(sizeof(char) * num);
  4. }
  5. void Test(void)
  6. {
  7. char *str = NULL;
  8. GetMemory(str, 100); //str仍未NULL
  9. strcpy(str, "hello"); //运行错误
  10. }

原因是编译器总是为每个参数制作临时副本。指针参数p, 其副本为_p,使_p=p。如果改变了_p所指的内容,相应的p所指的内容也跟着改变(毕竟指向同样的地方)。但是在GetMemory中动态分配内存空间,改变了_p的内容。在调用函数中的p还是指向NULL。再者,因为函数GetMemory中动态分配了空间,但是没释放,这样调用一次函数,就泄露了一次内存。图示:

如果非得用指针参数申请内存,可以用指针的指针作为参数申请内存

  1. void GetMemory(char **p, int num)
  2. {
  3. *p = (char *)malloc(sizeof(char) * num);
  4. }
  5. void Test(void)
  6. {
  7. char *str = NULL;
  8. GetMemory(&str, 100); //记得加地址符
    strcpy(str, "hello");
    free(str)
  9. }

原理是一样的,比较难理解,图示表示:

比较好的方法是传指针的引用

  1. #include <iostream>
  2. #include <string>
  3. #include <cstring>
  4. #include <cstdlib>
  5. using namespace std;
  6. void GetMemory(char *&p, int num)
  7. {
  8. p = (char *)malloc(sizeof(char) * num);
  9. }
  10.  
  11. void Test(void)
  12. {
  13. char *str = NULL;
  14. GetMemory(str, 100);
  15. strcpy(str, "hello");
  16. cout << str << endl;
  17. free(str);
  18. }
  19. int main()
  20. {
  21. Test();
  22. }

这里注意指针的引用 为char* &a,要是不好理解可以这样:

  1. typedef char* pchar;
  2. pchar &a

返回值策略

可以用函数返回值来传递动态内存。这中方法比“指针的指针”简单多了

  1. char *GetMemory(int num)
  2. {
  3. char *p = (char *)malloc(sizeof(char) * num);
  4. return p;
  5. }
  6. void Test(void)
  7. {
  8. char *str = NULL;
  9. str = GetMemory(100); //str指向了动态分配的空间
  10. strcpy(str, "hello");
  11. free(str)
  12. }

在使用返回值时,千万别返回指向“栈内存”的指针、引用,因为该内存在函数结束时自动消亡了,返回的指针是个野指针了。例如

  1. char *GetString()
  2. {
  3. char p[] = "hello world"; //数组内容存储在栈区,函数结束时,会释放掉
  4. return p;
  5. }
  6. void Test(void)
  7. {
  8. char *str = NULL;
  9. str = GetString(); //因为非配的内存早已释放掉,此时的str是个野指针,内容是垃圾
  10. cout << str << endl;
  11. }

在函数中不定义数组,定义指针,示例:

  1. char *GetString()
  2. {
  3. char *p = "hello world"; //数组内容存储在静态区,函数结束时,不会释放掉
  4. return p;
  5. }
  6. void Test(void)
  7. {
  8. char *str = NULL;
  9. str = GetString();
  10. cout << str << endl;
  11. }

此时的程序是正确的,但是有一点,此时分配的内存处于静态区,是只可以读取但是不可以修改的。

【VS开发】【C/C++开发】C++参数策略传递内存的更多相关文章

  1. Web开发基本准则-55实录-缓存策略

    续上篇<Web开发基本准则-55实录-Web访问安全>. Web开发基本准则-55实录-缓存策略 郑昀 创建于2013年2月 郑昀 最后更新于2013年10月26日 提纲: Web访问安全 ...

  2. 《JavaScript设计模式与开发实践》读书笔记之策略模式

    1.策略模式 定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换 1.1 传统实现 根据工资基数和年底绩效来发送年终奖 var calculateBonus= function (perfo ...

  3. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  4. iOS开发系列--并行开发其实很容易

    --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的, ...

  5. Spark集群 + Akka + Kafka + Scala 开发(1) : 配置开发环境

    目标 配置一个spark standalone集群 + akka + kafka + scala的开发环境. 创建一个基于spark的scala工程,并在spark standalone的集群环境中运 ...

  6. 嵌入式开发平台-iTOP-4418开发板

    详情转自:http://topeetboard.com S5P4418核心板可以无缝支持核心系统S5P6818,并保持底板设计不变,将兼顾更高端 的应用领域,为项目和产品提供更好的灵活性以及可伸缩性. ...

  7. Web程序员开发App系列 - 开发我的第一个App,源码下载

    Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...

  8. Loadrunner 脚本开发-利用loadrunner开发Windows Sockets协议脚本

    脚本开发-利用loadrunner开发Windows Sockets协议脚本 by:授客 QQ:1033553122 欢迎加入软件性能测试交流QQ群:7156436 实践举例 Socket服务端简单实 ...

  9. 带你从零学ReactNative开发跨平台App开发(一)

    ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...

随机推荐

  1. .net 中跨域问题

    1.ashx跨域接口 context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); 2.w ...

  2. Educational Codeforces Round 33 (Rated for Div. 2) B题

    B. Beautiful Divisors Recently Luba learned about a special kind of numbers that she calls beautiful ...

  3. 利用状态机(FSM)进行简单的uart串口发送数据

    module uart_tx(clk,rst_n,key,txd); input clk; input rst_n; input key; output reg txd; :] state; :] b ...

  4. Spring Cloud Eureka(四):Eureka 配置参数说明

    Eureka Client 配置项(eureka.client.*) org.springframework.cloud.netflix.eureka.EurekaClientConfigBean 参 ...

  5. Leetcode题目200.岛屿数量(BFS+DFS+并查集-中等)

    题目描述: 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. 示例 ...

  6. cs231n lecture2 image classification

    1.图片分类若采用最近邻法: import numpy as np class NearestNeighbor: def _init_(self): pass def train(self, X, y ...

  7. (转)ON DUPLICATE KEY UPDATE --mysql的一个有趣语法

    转自:http://my.oschina.net/iceman/blog/53735?fromerr=3kAEPcQr 如果在INSERT语句末尾指定了ON DUPLICATE KEY UPDATE, ...

  8. POJ 1135 -- Domino Effect(单源最短路径)

     POJ 1135 -- Domino Effect(单源最短路径) 题目描述: 你知道多米诺骨牌除了用来玩多米诺骨牌游戏外,还有其他用途吗?多米诺骨牌游戏:取一 些多米诺骨牌,竖着排成连续的一行,两 ...

  9. js回调函数(callback)(转载)

    学习jquery时,对回调函数感觉很困惑,在晚上找了半天,忽然发现这篇文章很浅显,基本说明了问题.故转载 原文: 自学jquery的时候,看到一英文词(Callback),顿时背部隐隐冒冷汗.迅速go ...

  10. P4124 [CQOI2016]手机号码

    P4124 [CQOI2016]手机号码 题解 数位DP   DFS  虽然套路,但还是恶心到找不到锅在哪里 注意这个 然后你就发现其实这样就不用记录前导0了 锅在这个鬼地方QAQ 代码 #inclu ...