在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* 的解决方案的更多相关文章

  1. sql 中sum函数返回null的解决方案

    SUM 是SQL语句中的标准求和函数,如果没有符合条件的记录,那么SUM函数会返回NULL. 但多数情况下,我们希望如果没有符合条件记录的情况下,我们希望它返回0,而不是NULL,那么我们可以使用例如 ...

  2. C++ 调用webservice 出现 函数返回值为 3 (SOAP_TAG_MISMATCH) 的解决方案

    最近在用C++ gsoap做webservice服务时,函数返回值为SOAP_TAG_MISMATCH (==3)错误码,原因是我传入wsdl地址时连同后面的?wsdl都传入了,如下: http:// ...

  3. Entity Framework 6 Recipes 2nd Edition(11-1)译 -> 从“模型定义”函数返回一个标量值

    第11章函数 函数提供了一个有力代码复用机制, 并且让你的代码保持简洁和易懂. 它们同样也是EF运行时能利用的数据库层代码.函数有几类: Rowset Functions, 聚合函数, Ranking ...

  4. Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 为一个”模型定义”函数返回一个计算列

    11-3. 为一个”模型定义”函数返回一个计算列 问题 想从”模型定义”函数里返回一个计算列 解决方案 假设我们有一个员工(Employee)实体,属性有: FirstName, LastName,和 ...

  5. Entity Framework 6 Recipes 2nd Edition(11-5)译 -> 从”模型定义”函数返回一个匿名类型

    11-5. 从”模型定义”函数返回一个匿名类型 问题 想创建一个返回一个匿名类型的”模型定义”函数 解决方案 假设已有游客(Visitor) 预订(reservation)房间(hotel ) 的模型 ...

  6. C++函数返回局部指针变量

    遇到过好几次关于函数返回指针变量问题,有时候是可以的,有时候是不可以的,然后就混乱了.今天研究了下,结果发现原来和内存分配有关. 用下面的例子分析下吧: char * test() { char a[ ...

  7. c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)

    C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...

  8. 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 ...

  9. Linux下tcp协议socket的recv函数返回时机分析(粘包)

    http://www.vckbase.com/index.php/wv/10http://blog.csdn.net/zlzlei/article/details/7689409 文章一: 当前在网络 ...

随机推荐

  1. web项目环境搭建(2):整合SpringMVC+velocity

    velocity是一个基于java的模板引擎.velocity应用于web开发时,前端设计人员可以只关注页面的显示效果,而java程序人员只关注业务逻辑代码.velocity将java代码从web页面 ...

  2. swing——JFrame基本操作

    用JFrame(String String1)创建一个窗口 public void setBounds(int a,int b,int width,int height)设置窗口初始化的位置(a,b) ...

  3. QT5-控件-QLabel和QLCDNumber-标签显示图片或者视频,LCD用于上位机不错

    #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QLabel> #incl ...

  4. 数据库触发器new old

    数据库触发器new old: "NEW . column_name"或者"OLD . column_name".这样在技术上处理(NEW | OLD . col ...

  5. js获取url?后的参数

    function GetRequest() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new O ...

  6. ADO.NET 新特性之SqlBulkCopy(批量插入大量数据)

    转自:http://blog.csdn.net/huaer1011/article/details/2312361 在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,还 ...

  7. phpcms v9联动菜单实现筛选

    <!--初始化init--> {php $theurl = "index.php?m=content&c=index&a=lists&catid=$cat ...

  8. Linux_shell条件判断if中的-a到-z的意思

    [ -a FILE ]  如果 FILE 存在则为真.  [ -b FILE ]  如果 FILE 存在且是一个块特殊文件则为真.  [ -c FILE ]  如果 FILE 存在且是一个字特殊文件则 ...

  9. java之多线程的理解

    线程的属性 (1)线程的状态     线程在它的生命周期中可能处于以下几种状态之一: New(新生):线程对象刚刚被创建出来: Runnable(可运行):在线程对象上调用start方法后,相应线程便 ...

  10. 更改xcode上iphone模拟器颜色的方法--备用

    到模拟器的目录下修改图片即可——在Finder中显示,显示模拟器包内容,修改Contents/Resources/frame.png图片!