Chinaunix

标题: 函数可以返回一个这样的char数组吗? [打印本页]

作者: avcodec    时间: 2009-08-24 16:03
标题: 函数可以返回一个这样的char数组吗?
想把一个CString类型的字符串转换成char*,写了一个这样的函数:

char* StringToChars(CString srcstr)
{
        int len = srcstr.GetLength();
        if (len <= 0)
                        return NULL;

        char chs[255];
        memset(chs, 0, sizeof(chs));
        for (int k=0; k<srcstr.GetLength(); k++)
        {
                  if (k>=255)
                                break;

                 chs[k] = (char)srcstr.GetAt(k);
        }
       
        return chs;
}

实际验证后,是可以正常工作的。但心里有点没底,所以来问一下。
我的理解:因为chs数组是在函数中分配的,好像内存应该是分配在栈上的,函数结束后,这片内存就失效了,按说返回值是不可用的。
作者: carol_sun    时间: 2009-08-24 16:03
你这段代码使用正常,是因为该数组占用的那片内存还没有被覆盖而已,事实上它已经无效了
作者: net_robber    时间: 2009-08-24 16:04
不可以
作者: net_robber    时间: 2009-08-24 16:05
不能返回数组,只能返回指针
作者: hellioncu    时间: 2009-08-24 16:11
MFC?没用Unicode之类的吧,用(LPCSTR)srcstr就可以了得到指针了
作者: upoq    时间: 2009-08-24 16:13
标题: 回复 #1 avcodec 的帖子
加 static

static char chs[255];
作者: snyh    时间: 2009-08-24 16:21
原帖由 upoq 于 2009-8-24 16:13 发表
加 static

static char chs[255];



static虽然可以   但不该这么用


在函数里面自己用malloc分配空间   
或者传入一个已经分配好的空间地址给  函数
作者: upoq    时间: 2009-08-24 16:27
标题: 回复 #7 snyh 的帖子
针对楼主的提问,加 static 是最合适的回答。
“在函数里面自己用malloc分配空间”不可取!   
“传入一个已经分配好的空间地址给函数”可以。
作者: 群雄逐鹿    时间: 2009-08-24 16:29
return 一个结构

struct
{
     chs[255];
};
作者: upoq    时间: 2009-08-24 16:37
标题: 回复 #7 snyh 的帖子
另外,如果不是多线程重入,static 也是不错的选择。
函数可以这样设计:
如果数组够长,返回 char*; 如果数组不够长返回 NULL 。

[ 本帖最后由 upoq 于 2009-8-24 16:41 编辑 ]
作者: avcodec    时间: 2009-08-24 16:58
测试程序正常,放到程序中已经不正常了。重新修改了一下:
char* StringToChars(CString srcstr)
{
        int len = srcstr.GetLength();
        if (len <= 0)
                return NULL;

        char *chs = new char[len+1];                                  // 这儿动态分配内存了
        memset(chs, 0, len+1);
        for (int k=0; k<srcstr.GetLength(); k++)
        {
                chs[k] = (char)srcstr.GetAt(k);
        }
       
        return chs;
}

这样倒是正常了。但这片内存如何释放呢。
char *chs = StringToChars(CString srcstr);

delete []chs,还是直接delete chs呢?
作者: upoq    时间: 2009-08-24 17:03
标题: 回复 #11 avcodec 的帖子
不要这样设计
作者: avcodec    时间: 2009-08-24 17:19
楼上有什么好的建议吗?
作者: alexhappy    时间: 2009-08-24 17:35
给函数加个参数,如
void StringToChars(CString srcstr,char *pChar)
{
        int len = srcstr.GetLength();
        if (len <= 0)
                return NULL;

        char *chs = pChar;                                  // 这儿动态分配内存了
        memset(chs, 0, len+1);
        for (int k=0; k<srcstr.GetLength(); k++)
        {
                chs[k] = (char)srcstr.GetAt(k);
        }
        
}
这样就既不需要动态分配内存,当然没有释放的问题了

[ 本帖最后由 alexhappy 于 2009-8-24 17:38 编辑 ]
作者: snyh    时间: 2009-08-24 18:20
在函数里面分配就是 由 实现者分配内存  调用者需要处理释放问题

传递一个已经分配的内存到函数就是  调用者实现分配和释放

static  绝对不适合
1 因为没地方可以释放内存 (这还是小事)
2 你无法知道需要多少空间来存放数组
3 你第二次使用的时候 之前的内存内容就会被覆盖 (针对楼主的问题 这一点是致命的 竟然还说static针对楼主的问题最适合


upoq 说不要在函数里面分配内存
也许是对的  我没什么经验 只是看到有地方这样做

但glib里面有很多函数都是 由实现者分配内存  ( 也许glib设计的不好)

相对来说 实现者分配内存 容易出错 不释放内存 但至少会比用static 好吧
static应该不适合用在分配内存   而非常适合保持需要由‘记忆’能力的标量类变量


但我个人认为  这俩种应该视情况实现  而不能说  不能设计成实现者分配内存

因为释放问题 不管是由谁 实现  如果程序员本身没有注意 那么都会出现问题
而如果程序员本身由注意 两种方式 都不会由问题


只是看在那分配内存方便

个人意见

观望高人 看法

alexhappy 你这个不就是调用者分配内存嘛。。。。不一样要分配内存
被你的 不用分配内存  这句给唬住了。。。。

群雄逐鹿
的办法也许是最好的吧   不过好像只有在测试的时候有用。。
因为也无法知道 具体需要多少内存 就无法构造一个结构体。。。而且为了一个数组去弄个结构体。。。
还有一点 返回结构体    是在栈中 通过传值 返回
速度肯定没传递个指针快  而且如果需要的内存太大   栈还溢出的可能性

[ 本帖最后由 snyh 于 2009-8-25 08:23 编辑 ]
作者: snyh    时间: 2009-08-24 18:23
还有一种
就是传递一个 **p 参数进去  分配内存由实现者  实现
释放内存由调用者实现

这样也许会好点吧。。。。 因为变量是由实现者定义的 所以也许会更好的注意 释放问题。。。
(glib里面 对传递 GError时候好像都是这样实现的)
作者: avcodec    时间: 2009-08-25 10:35
还是打算采用在11楼修改过的方式。这样比较符合类型转换函数的形式。
但有个问题,程序运行结束后,vc会给出内存泄露的提示,显示在这一行:
char *chs = new char[len+1];   。
已经采用delete []释放了内存,为什么还会有提示呢。
作者: avcodec    时间: 2009-08-25 10:49
是有一个地方的释放内存遗漏了。问题解决了。

谢谢大家的回复。
作者: liklone    时间: 2009-08-25 11:08
原帖由 upoq 于 2009-8-24 16:27 发表
针对楼主的提问,加 static 是最合适的回答。
“在函数里面自己用malloc分配空间”不可取!   
“传入一个已经分配好的空间地址给函数”可以。


严重同意!
作者: snyh    时间: 2009-08-25 11:18
原帖由 liklone 于 2009-8-25 11:08 发表


严重同意!



楼主的这个函数是把 string 转换为char *
也就是一个工具函数 应该是比较常用的。。。。

那么如果我转换   string_one  之后想要转换 string_two 怎么办?
之前的char*会因为是static 所以 会被覆盖    (你可以在再次调用前保存起来  用malloc那何必 而且极容易出问题)

而且static数组的大小也不好分配   用动态数组?  如果第一次我传递的一个string 只有一个字节 呢?  那以后怎么办


所以static  不是不好的方式  在这里 完全就是错误的方式
作者: pcwkt    时间: 2009-08-25 11:31
CString 没有 c_str() ?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2