函数返回char* 的解决方案
在C语言中,自动变量在堆栈中分配内存。当包含自动变量的函数或代码块退出时,它们所占用的内存便被回收,它们的内容肯定会被下一个所调用的函数覆盖。这一切取决于堆栈中先前的自动变量位于何处,活动函数声明了什么变量,写入了什么内容等。原先自动变量地址的内容可能被立即覆盖,也可能稍后才被覆盖。
解决方案:
1. 返回一个指向字符串常量的指针。例如:
char* func() {
return "Only works for simple strings";
}
这是最简单的解决方案,但如果你需要计算字符串的内容,它就无能为力了,在本例中就是如此。如果字符串常量存储于只读内存区,但以后需要改写它时,你就会有麻烦了。
2. 使用全局声明的数组。
char* fun() {
.................
global_array[i] = ....;
return global_array;
}
这适用于自己创建字符串的情况,也很简单易用。它的缺点在于任何人都有可能在任何地方任何时候修改这个全局数组。
3. 静态数组。例如:
char* func() {
static char buffer[];
...
return buffer;
}
这就可以防止任何人任何时候修改这个数组。只有拥有指向该数组的指针的函数(通过参数传递给它)才能修改这个静态数组。但是,该函数的下一次调用将覆盖这个数组的内容,所以调用者必须在此之前使用或者备份数组的内容。和全局数据一样,大型缓冲区如果闲置不用是非常浪费内存空间的。
4. 显式分配一些内存,保存返回的值。例如:
char* func() {
char *s = malloc();
...
return s;
}
这个方法具有静态数组的优点,而且在每次调用时都创建一个新的缓冲区,所以该函数以后的调用不会覆盖以前的返回值。它适用于多线程的代码。它的缺点在于程序猿必须承担内存管理的责任。根据程序的复杂程度,这项任务可能很容易,也可能很复杂。如果内存尚在使用就释放或者出现“内存泄露”(不再使用的内存未回收),就会产生令人难以置信的Bug。人们非常容易释放已分配的内存。
5. 也许最好的解决方案就是要求调用者分配内存来保存函数的返回值。为了提高安全性,调用者应该同时指定缓冲区的大小。
void func(char *result, int size)
{
...
strncpy(result, "That' d be in the data segment, Bob", size); } buffer = malloc (size);
func(buffer);
...
free(buffer);
如果程序员在同一块代码中同时进行“malloc” 和“free”操作,内存管理最为轻松。
6. const char* 返回
//错误
char* Func(void)
{
char str[] = "hello world";
return str;
} //正确
const char* Func(void)
{
const char* p = "hello world";//字符串常量存放在程序的静态数据区
return p;
}
函数返回char* 的解决方案的更多相关文章
- sql 中sum函数返回null的解决方案
SUM 是SQL语句中的标准求和函数,如果没有符合条件的记录,那么SUM函数会返回NULL. 但多数情况下,我们希望如果没有符合条件记录的情况下,我们希望它返回0,而不是NULL,那么我们可以使用例如 ...
- C++ 调用webservice 出现 函数返回值为 3 (SOAP_TAG_MISMATCH) 的解决方案
最近在用C++ gsoap做webservice服务时,函数返回值为SOAP_TAG_MISMATCH (==3)错误码,原因是我传入wsdl地址时连同后面的?wsdl都传入了,如下: http:// ...
- Entity Framework 6 Recipes 2nd Edition(11-1)译 -> 从“模型定义”函数返回一个标量值
第11章函数 函数提供了一个有力代码复用机制, 并且让你的代码保持简洁和易懂. 它们同样也是EF运行时能利用的数据库层代码.函数有几类: Rowset Functions, 聚合函数, Ranking ...
- Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 为一个”模型定义”函数返回一个计算列
11-3. 为一个”模型定义”函数返回一个计算列 问题 想从”模型定义”函数里返回一个计算列 解决方案 假设我们有一个员工(Employee)实体,属性有: FirstName, LastName,和 ...
- Entity Framework 6 Recipes 2nd Edition(11-5)译 -> 从”模型定义”函数返回一个匿名类型
11-5. 从”模型定义”函数返回一个匿名类型 问题 想创建一个返回一个匿名类型的”模型定义”函数 解决方案 假设已有游客(Visitor) 预订(reservation)房间(hotel ) 的模型 ...
- C++函数返回局部指针变量
遇到过好几次关于函数返回指针变量问题,有时候是可以的,有时候是不可以的,然后就混乱了.今天研究了下,结果发现原来和内存分配有关. 用下面的例子分析下吧: char * test() { char a[ ...
- c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)
C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...
- PHP使用empty检查函数返回结果时报Fatal error: Can't use function return value in write context的问题
PHP开发时,当你使用empty检查一个函数返回的结果时会报错:Fatal error: Can't use function return value in write context 例如: &l ...
- Linux下tcp协议socket的recv函数返回时机分析(粘包)
http://www.vckbase.com/index.php/wv/10http://blog.csdn.net/zlzlei/article/details/7689409 文章一: 当前在网络 ...
随机推荐
- grep和正则表达式
正则表达式示例表字 符 意 义 示 例* 任意长度的字符串. a* 表示: 空字符串.aaaa.a…? 长度为0或者1的字符串. a? 表示: 空字符串和a.+ 长度为一个或者多个的字符串. a+表示 ...
- C++小技巧之四舍五入与保留小数
四舍五入:保留整数 int a = b+0.5; 保留一位小数 int a=(b+0.05)*10; double c=a/10; 保留二位小数 int a=(b+0.005)*100; doub ...
- web项目环境搭建(2):整合SpringMVC+velocity
velocity是一个基于java的模板引擎.velocity应用于web开发时,前端设计人员可以只关注页面的显示效果,而java程序人员只关注业务逻辑代码.velocity将java代码从web页面 ...
- 跟我学android-搭建Android开发环境(一)
Android官网地址:http://developer.android.com/,下载和安装 AndroidSDK请按如下步骤进行: 下载ADT 和SDK:http://developer.andr ...
- STL删除vector或list的方法及注意的问题
删除vector中的元素 1.删除指定的所有对象 STL中remove()只是将待删除元素之后的元素移动到vector的前端,而不是删除.若要真正移除,需要搭配使用erase().例子: vector ...
- 如何往IE工具条添加按钮(转载)
如何往IE工具条添加按钮 问题提出:金山词霸.网络蚂蚁等软件安装后会向IE的工具条添加自己的按钮.按下按钮后还会作出相应的动作,这种功能是如何实现的呢?读完本文,您也可以将自己应用程序的按钮添加到IE ...
- 自定义窗口 mfc
typedef struct _WNDCLASS { UINT style; //制定窗口的类型 WNDPROC lpfnWndProc; int cbClsExtra; //额外的数值 int cb ...
- CSS定位与浮动
定位的基本思想很简单,它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素.另一个元素甚至浏览器窗口本身的位置.显然,这个功能非常强大,也很让人吃惊.要知道,用户代理对 CSS2 中定位 ...
- jquery validation插件使用
首先需要引入jQuery.js和jquery.validate.js 以下面代码为例: <form id="mainform"> <fieldset> &l ...
- 博客迁移至http://www.maxzhang.com,欢迎访问!
博客迁移至http://www.maxzhang.com,欢迎访问!