【VS开发】【C/C++开发】C++参数策略传递内存
参数策略
如果函数的参数是一个指针,不要指望用该指针去动态申请内存。如下:

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"); //运行错误
}

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

void GetMemory(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100); //记得加地址符
strcpy(str, "hello");
free(str)
}

原理是一样的,比较难理解,图示表示:
比较好的方法是传指针的引用

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
void GetMemory(char *&p, int num)
{
p = (char *)malloc(sizeof(char) * num);
} void Test(void)
{
char *str = NULL;
GetMemory(str, 100);
strcpy(str, "hello");
cout << str << endl;
free(str);
}
int main()
{
Test();
}

这里注意指针的引用 为char* &a,要是不好理解可以这样:
typedef char* pchar;
pchar &a
返回值策略
可以用函数返回值来传递动态内存。这中方法比“指针的指针”简单多了

char *GetMemory(int num)
{
char *p = (char *)malloc(sizeof(char) * num);
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory(100); //str指向了动态分配的空间
strcpy(str, "hello");
free(str)
}

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

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

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

char *GetString()
{
char *p = "hello world"; //数组内容存储在静态区,函数结束时,不会释放掉
return p;
}
void Test(void)
{
char *str = NULL;
str = GetString();
cout << str << endl;
}

此时的程序是正确的,但是有一点,此时分配的内存处于静态区,是只可以读取但是不可以修改的。
【VS开发】【C/C++开发】C++参数策略传递内存的更多相关文章
- Web开发基本准则-55实录-缓存策略
续上篇<Web开发基本准则-55实录-Web访问安全>. Web开发基本准则-55实录-缓存策略 郑昀 创建于2013年2月 郑昀 最后更新于2013年10月26日 提纲: Web访问安全 ...
- 《JavaScript设计模式与开发实践》读书笔记之策略模式
1.策略模式 定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换 1.1 传统实现 根据工资基数和年底绩效来发送年终奖 var calculateBonus= function (perfo ...
- iOS开发系列--网络开发
概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...
- iOS开发系列--并行开发其实很容易
--多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的, ...
- Spark集群 + Akka + Kafka + Scala 开发(1) : 配置开发环境
目标 配置一个spark standalone集群 + akka + kafka + scala的开发环境. 创建一个基于spark的scala工程,并在spark standalone的集群环境中运 ...
- 嵌入式开发平台-iTOP-4418开发板
详情转自:http://topeetboard.com S5P4418核心板可以无缝支持核心系统S5P6818,并保持底板设计不变,将兼顾更高端 的应用领域,为项目和产品提供更好的灵活性以及可伸缩性. ...
- Web程序员开发App系列 - 开发我的第一个App,源码下载
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- Loadrunner 脚本开发-利用loadrunner开发Windows Sockets协议脚本
脚本开发-利用loadrunner开发Windows Sockets协议脚本 by:授客 QQ:1033553122 欢迎加入软件性能测试交流QQ群:7156436 实践举例 Socket服务端简单实 ...
- 带你从零学ReactNative开发跨平台App开发(一)
ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...
随机推荐
- vue 多层组件相互嵌套的时候 数据源更新 dom没更新 彻底清除组件缓存
当项目中存在多层组件相互嵌套 组件存在严重缓存时 this.$nextTick(() => { ..... }); 不管用 this.$forceUpdate(); 不管用 只能通过深拷贝浅拷 ...
- Git可视化极简易教程 — Git GUI使用方法[转]
之前一直想一篇这样的东西,因为最初接触时,我也认真看了廖雪峰的教程,但是似乎我觉得讲得有点多,而且还是会给我带来很多多余且重复的操作负担,所以我希望能压缩一下它在我工作中的成本,但是搜索了一下并没有找 ...
- [Algorithm] Chunk Array
// --- Directions// Given an array and chunk size, divide the array into many subarrays// where each ...
- JavaScript三元运算符
㈠条件运算符也叫做三元运算符 ⑴语法:条件表达式?语句1:语句2: ⑵执行的流程: ①条件运算符在执行时,首先对条件表达式进行求值 ▶如果该值为true,则执行语句1,并返回执行结果 ▶如果该值为fa ...
- php判断文件是否为txt文件
可以使用pathinfo方法来通过后缀名进行判断文件类型. /** * 获取文件后缀(如果文件名为11.11,11不是后缀,会默认11为后缀) * $file string 文件路径或者文件名 */ ...
- neo4j︱与python结合的py2neo使用教程
—- 目前的几篇相关:—– neo4j︱图数据库基本概念.操作罗列与整理(一) neo4j︱Cypher 查询语言简单案例(二) neo4j︱Cypher完整案例csv导入.关系联通.高级查询(三) ...
- 用javascript来判别回文数
什么是回文数?通俗的说就是正着读和倒着读都一样的字符串(即使是数字也是可以看成字符串的). 所以下面回文数都是用字符串来表示的,即判断回文数就是对字符串的判断. 举几个回文数的例子: i love u ...
- python 系统模块 OS
os.system("系统命令") 调用系统命令 os.system("task kill /f /im 系统的进程") 关闭系统进程 os.listdir( ...
- HTTP第八、九章之网关、隧道、web机器人
网关 网关(gateway): 资源和应用程序之间的粘合剂.应用程序可以(通过HTTP或其它已定义的接口)请求网关来处理某条请求,网关可以提供一条响应.网关可以向数据库发送查询语句,或者生成动态的内容 ...
- python 查看源代码
使用包inspect import inspect from mxnet import contrib 查看模块所在路径: inspect.getsourcefile(contrib) 查看源码: i ...