读书人

怎么正确返回函数内部new的char

发布时间: 2013-07-01 12:33:04 作者: rapoo

如何正确返回函数内部new的char
本帖最后由 lcy_888 于 2013-06-06 14:19:16 编辑 代码如下:
char* U2G(const char* utf8,string &out)
{
int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len+1];
memset(wstr, 0, len+1);
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len+1];
memset(str, 0, len+1);
WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
if(wstr)
delete[] wstr;
return str;
}

这样有内存泄漏,我必成如下形式但不能正确获取返回的值

std::string U2G(const char* utf8)
{
int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len+1];
memset(wstr, 0, len+1);
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len+1];
memset(str, 0, len+1);
WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
if(wstr) delete[] wstr;
std::string ret(str, len+1);
delete[] str;
return ret;
}
[解决办法]
第一段代码没看出有内存泄露,除非是调用这个函数的代码没有释放收到的字符串。
第二段代码中创建string时不正确,应该是std::string ret(str, len); len不要加1,否则string会把结束符也当作字符串的一部分;也可以std::string ret(str)。
[解决办法]
为什么非要在函数内部new出内存,还要然后返回给函数调用者?
内存管理一向是建议:函数自己创建,自己销毁。
U2G函数里new出来的内存,应该在U2G里面就delete掉才行。
既然要返回内存指针,在函数调用时,调用者就把已经申请好的内存指针作为参数传给U2G,U2G只要把内容写入就可以了,不要掺和申请,销毁内存。
这样定义函数
void U2G(const char* utf8,string &out,char *pRetBuffer)
[解决办法]
第一种情况应该由函数调用者来释放内存。。
第二种没问题。。只是你写错了而已。。直接std::string ret(str);即可。。
[解决办法]
“分配者负责释放”的规则可以让内存管理逻辑变得很清晰,但很可惜,这一规则并不是很好用。
比如面对楼主的问题,调用者要先分配内存,再调用U2G,但要先分配多大的内存呢?

唯一的办法就是把U2G分开,先获取所需长度,再实现转换。调用MultiByteToWideChar获取宽字符串的长度,为宽字符串分配内存,调用MultiByteToWideChar转换为宽字符串,WideCharToMultiByte获取结果长度,释放内存,返回长度;下次调用时再重新分配宽字符串,再调用MultiByteToWideChar……
很明显多余操作多了不少。

改一下吧,返回长度时把中间字符串也返回回去,并要示调用者下次调用时再传进来。可是某个调用者得到长度后就放弃了,你这个中间字符串谁来释放?

再改一下,不用一个函数,但要求调用者提供一个回调函数负责分配内存,在获取长度后调用这个函数……我怎么觉得越来越复杂了?

说远了,与题无关,抱歉抱歉。
[解决办法]
将new和delete象fopen和fclose那样用!

读书人网 >C++

热点推荐