作为一个介绍,请注意我是一个Java程序员,仍然习惯于C++中的内存管理问题。如何使这段代码更少的内存泄漏?
我们有一个基类,用于将对象编码为一串ASCII字符。本质上,类正在使用类成员将不同的数据类型转换为一个长字符串,然后将char*
返回给包含编码对象数据的调用方。
在测试内存泄漏时,我看到我们正在使用的实现似乎倾向于创建内存泄漏,因为用户必须始终记住要删除该方法的返回值。下面是代码的相关部分的摘录:
char* Msg::encode()
{
// clear any data from the stringstream
clear();
if (!onEncode()) {
return 0;
}
// need to convert stringstream to char*
string encoded = data.str();
// need to copy the stringstream to a new char* because
// stringstream.str() goes out of scope when method ends
char* encoded_copy = copy(encoded);
return encoded_copy;
}
bool Msg::onEncode(void)
{
encodeNameValue(TAG(MsgTags::TAG_USERID), companyName);
encodeNameValue(TAG(MsgTags::TAG_DATE), date);
return true;
}
bool EZXMsg::encodeNameValue(string& name, int value)
{
if(empty(value))
{
return true;
}
// data is stringstream object
data << name << TAG_VALUE_SEPARATOR << value << TAG_VALUE_PAIRS_DELIMITER;
return true;
}
char* copy(string& source) {
char *a=new char[source.length() +1];
a[source.length()]=0;
memcpy(a,source.c_str(),source.length());
return a;
}
UPDATE
嗯 - 我应该是关于encode()
结果如何消耗更准确。它传递给boost:async_write,并且程序崩溃,因为我认为字符串在async_write完成之前超出了范围。看起来我需要将返回的字符串复制到一个类成员,该成员在发送消息(?)的类的生命周期中是活着的。
这是encode()
方法实际使用的方式(后我改变了对string
返回值):
void iserver_client::send(ezx::iserver::EZXMsg& msg) {
string encoded = msg.encode();
size_t bytes = encoded.length();
boost::asio::async_write(socket_, boost::asio::buffer(encoded, bytes), boost::bind(&iserver_client::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
它看起来像正确的方式做,这是保持队列/列表/字符串向异步写入。如注释here(以及在boost chat_client示例中)。 (但这是一个单独的问题。)
这取决于期望的API是什么。一个大问题 - 返回的'char *'应该有效多久,谁应该释放与之关联的内存? –
为什么不直接从'encode()'方法返回一个'string'(或者传入一个'string'的引用)? –
不要使用'char *'作为返回类型;事实上,避免原始的'char *'字符串并使用'std :: string'。使用RAII(资源获取初始化)确保异常和正常使用避免泄漏。尽可能避免“新”;当你不能时非常小心。 –