LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: waa

一个C函数动态返回char *的问题

[复制链接]
发表于 2006-1-11 18:22:27 | 显示全部楼层
一般像这类的工具函数都是使用一个静态的变量:
char *itoa(const int integer, int radio)
{
static char a[2]
a[0] = 'F';
a[1] = '\0';
return a;
}

但是有个弊端就是不能这样使用:
printf("%d, %d", itoa(1), itoa(2));
因为后一次调用会覆盖前一次调用的值,所以有些就维护几个静态变量,前后调用的时候使用不同的变量,暂时不会被覆盖掉。而有些函数直接让用户传如分配好的内存,于是释放的工作留给了用户。
回复 支持 反对

使用道具 举报

发表于 2006-1-11 18:32:20 | 显示全部楼层
感觉在C世界这样的东西很常用,因为指针就是效率。当然对于初学者这样的玩法玩出火的可能性还是较高。
C++希望能更安全的使用,因此出现了RAII这样的概念,也是为了解决这类问题而不失高效,相比GC带来的效率问题要好的多。

但这并不说明哪种方式更好。在实际应用中,运用最合适的方式才是关键。资源管理真是永久的话题。
回复 支持 反对

使用道具 举报

发表于 2006-1-14 20:33:06 | 显示全部楼层
首先说明一点,你这么写肯定会有问题,而且是大问题!换句话说,是大错特错!
至于为什么能够返回正确的是,这是因为你释放的内存(delete a;)还没有被分配出去,所以它的值还暂时存在着,但是这块内存(&a)是可以随时被系统动态分配出去的,到那个时候你的这个变量a的值就改变了!!!

因此,当你delete一个动态分配的指针的时候,一个好的习惯就是马上把这个指针赋值为NULL,所以,当你delete a以后,应该加上一句:
a = NULL;

回到你的问题,主要还是一个谁申请,谁释放的问题。两种解决方法:
1)被调用者(callee)申请,调用者(caller)释放
在这样的情况下,你的itoa函数中不能delete a,要在主程序中使用完变量a以后,再delete!需要注意的是,所有调用函数itoa的程序,都要在使用以后,delete itoa函数返回的那个指针!!!这就要求你格外的注意了,稍有不慎,就会造成内存泄漏,当然了,如果是别人使用你的这个函数,而你又没有说明需要释放,则内存泄漏是肯定的。
2)调用者(caller)申请,调用者(caller)释放
这种情况比较稳妥,但是学要改变函数的声明方式,例如:

int itoa(const int integer, int radio, /*out*/ char *a)

这样,又调用itoa函数者来分配内存,并且负责释放。因此,在此种情况下比较稳妥。



Post by waa
例如这样一个函数
char *itoa(const int integer, int radio)
{
    char *a = new char[2];
    a[0] = 'F';
    a[1] = '\0';

    delete a;  // 问题就在这里

    return a;
}

这里,如果不释放内存的话是一定产生内存泄漏的;
但如果我在返回a前把内存释放掉(虽然返回后的结果是正确的),返回后的结果是不是很可能会出问题呢?

同类型的函数是怎样解决返回值的问题的呢?本人是新手,望高手赐教!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表