c/c++排坑(4) -- c/c++中返回局部变量
返回c语言中的局部变量
先看一段代码猜猜,打印值:
#include <iostream>
using namespace std;
char * func();
int main()
{
char *buf = func();
cout << "buf:" << buf << endl;
}
char * func()
{
char buffer[3];
buffer[0] = '1';
buffer[1] = '2';
buffer[2] = '3';
return buffer;
}
或许你已经猜到了,会打印乱码的值。原因是返回了一个局部的变量,而局部变量再离开函数体之后就不存在了,char 指针指向不明的空间。那么如何改进这玩意儿呢?
- 返回一个指向字符串常量的指针。
char * func() { return "123"; }
- 使用全局声明的数组。
这适用于自己创建的字符串情况,也很简单易用。它的缺点在于任何人都有可能在任何时候修改这个全局数组,而且该函数的下一次调用也会覆盖该数组的内容。 - 使用静态数组。
这就可以防止任何人修改这个值,但是该函数的下一次调用将覆盖整个数组的内容,所以调用者必须在此之前使用或备份数据的内容。和全局数组一样,大型缓冲区如果闲置不用是非常浪费内存空间的。
char * func()
{
static char buffer[3];
buffer[0] = '1';
buffer[1] = '2';
buffer[2] = '3';
return buffer;
}
- 显示分配一些内存,保存返回的值。整个方法其实挺不错的,但是缺点也非常明显,程序员必须承担内存管理的责任。我的天,在函数外还能想着给函数内的内存做释放的家伙得多变态。所以...嗯...我是受不了这种做法。
char * func()
{
char * buffer = malloc(10);
...
return buffer;
}
- 调用者分配内存来保存函数的返回值。为了提高安全性,调用者应该同时指定缓冲区的大小。
char * func(char * result, int size)
{
...
strncpy(result, "something", size);
}
buffer = malloc(size);
func(buffer, size);
...
free(buffer);
如果程序员可以在同一代码中同时进行malloc和free操作,内存管理是较为轻松的。
C++的一些情况
C++中当然在普通情况下和c无异。但是考虑如下代码,看看会打印啥:
#include <iostream>
#include <string>
using namespace std;
string func1();
int main()
{
string str = func1();
cout << "str:" << str << endl;
}
string func1()
{
string str("str123");
return str;
}
哈哈,显然你已经猜到不会打印乱码了。为啥同样是局部变量,string类型不会打印乱码呢。这是因为在C++中,返回的时候会有一个临时变量来保存这个返回值哦。同样的在输入的时候也是通过生成临时变量传参的。考虑如下代码:
void func(Object obj)
{
...
}
如果Object 是一个复杂的对象,那么其实是非常影响性能的,可考虑改成如下的代码:
void func(const Object &obj)
{
...
}
咦,是不是很熟悉呢。其实很多代码都是这样做的哈。这里的const表示不可修改,其实const关键字还真是容易让人理解错呢,将const理解成readonly大多数情况下不会错。
See you next time. Happy Coding!!!
我的github
c/c++排坑(4) -- c/c++中返回局部变量的更多相关文章
- 排坑·IPhone&IOS中不兼容正则中的断言匹配
阅文时长 | 1.14分钟 字数统计 | 1834.4字符 主要内容 | 1.问题切入 2.什么是断言匹配 3.断言匹配的替换方案 4.声明与参考资料 『排坑·IPhone&IOS中不兼容正则 ...
- c/c++排坑(5) -- c语言中的申明
C语言的申明总是令人头大,对于这块内容也一直让我头疼.希望通过这篇博客能够稍微梳理一下.材料和例子来源于<C专家编程> 一.C语言的申明的优先级规则 先来个例子,看看下面这行C代码到底是个 ...
- c/c++排坑(3) -- c/c++中的switch语句
switch语句的简单介绍 一个 switch 语句允许测试一个变量等于多个值时的情况.每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查. switch(expres ...
- c/c++排坑(2) -- c语言中的符号重载
所谓的符号重载就是在不同的上下文环境里有不同的意义.甚至有些关键字也被重载而具有好几种意义,这也是C语言的作用域规则对程序员不那么清晰的主要原因. 本章内容摘自<c专家编程>P37. 大家 ...
- Spring-Cloud之Eureka排坑之旅
1 快速demo 1.0 环境说明 Intelli IDEA+Spring Boot 1.1 新建工程chap52(通过New Project->Spring Initializer-> ...
- element UI排坑记(一):判断tabs组件是否切换
之所以将这个问题列在排坑记之中,是因为官方组件的一个属性颇有些隐蔽,这个问题曾经折腾了本人较多时间,始终思维固着,且使用搜索引擎也不容易搜索到答案,故记之.然而实际解决却是相当简单的. 一.问题描述 ...
- 排坑·ASCII码为160的空格(nbsp)
阅文时长 | 2.83分钟 字数统计 | 1345.2字符 『排坑·ASCII码为160的空格(nbsp)』 编写人 | SCscHero 编写时间 | Wednesday, September 9, ...
- php萌新|学习|排坑|のmysqli_error()方法的妙用
从开始学习php当现在已经有一个月多.除了每天完成公司布置的日常汇报,也没有耐下性子写一写自己想写的东西.今天就当起个头,坚持一周有个两三片文章或者小总结,也不枉费自己的付出.(我自己都不信,你会信吗 ...
- ToolProvider.getSystemJavaCompiler()方法空指针的排坑
起因: 我在做一个编译Java代码的功能,基本写的差不多了,我就想把它打包部署到我服务器上跑一跑,但是这不做不知道,一做果然就出了问题.我在IDEA上跑一点问题都没有,但是打包成Jar后,后台就显示空 ...
随机推荐
- LeetCode 884. Uncommon Words from Two Sentences (两句话中的不常见单词)
题目标签:HashMap 题目给了我们两个句子,让我们找出不常见单词,只出现过一次的单词就是不常见单词. 把A 和 B 里的word 都存入 map,记录它们出现的次数.之后遍历map,把只出现过一次 ...
- mac 下安装Anaconda Python
# 将anaconda的bin目录加入PATH echo 'export PATH="/Users/work/anaconda/bin/:$PATH"' >> ~/.b ...
- 【Ubuntu】无法挂载磁盘
我的电脑分了三个分区,A,B,C,其中A和B是Windows盘,C是ubuntu系统盘 某日发现A ,B盘没法进入了,在文件管理器中点一下,没有反应.于是右击盘符,点击挂载,跳出错误信息: (划重点) ...
- git reset --hard 回滚以后 以后怎么再回去?
恢复的过程很简单: 通过git log -g命令来找到需要恢复的信息对应的commitid,可以通过提交的时间和日期来辨别,找到执行reset --hard之前的那个commit对应的commitid ...
- visual studio推荐的插件
https://marketplace.visualstudio.com/items?itemName=EricLebetsamer.BootstrapSnippetPack https://mark ...
- js【面向过程编程】、好、 【init()、 GetData()、 bindData()、bindDom、 bindEvent()、buyProduct()、AddProductToCart()】*****************
1. 一般页面开发方式 [可读性差.可维护性差]------初级开发工程师 一般页面编写方法 var name = 'iphone8' var description = '手机中的战斗机 ' var ...
- bzoj 3312 No Change
题目大意: 到商场购物,他的钱包里有K个硬币 想按顺序买 N个物品,第i个物品需要花费c(i)块钱 在依次进行的购买N个物品的过程中,可以随时停下来付款,每次付款只用一个硬币 支付购买的内容是从上一次 ...
- 特征变化--->索引到标签的转换(IndexToString)
package Spark_MLlib import org.apache.spark.ml.feature.{IndexToString, StringIndexer} import org.apa ...
- android api level对应表(copy)
Platform Version API Level VERSION_CODE Notes Android 4.4 19 KITKAT Platform Highlights Android 4.3 ...
- Linux进程状态解析
引言 Linux是一个多用户,多任务的系统,可以同时运行多个用户的多个程序,就必然会产生很多的进程,而每个进程会有不同的状态. 在下文将对进程的R.S.D.T.Z.X 六种状态做个说明. PROCE ...