はじめに、私は Java プログラマーであり、C++ でのメモリ管理の問題にまだ慣れていないことに注意してください。
オブジェクトをASCII文字の文字列にエンコードするために使用される基本クラスがあります。基本的に、クラスはクラス メンバーを使用してさまざまなデータ型を 1 つの長い文字列に変換し、エンコードされたオブジェクト データを含む を呼び出し元にstringstream
返します。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;
}
アップデート
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));
}
これを行う適切な方法は、非同期書き込みする文字列のキュー/リスト/ベクトルを維持することです。ここに記載されているように(およびブーストの chat_client サンプルにも)。(しかし、それは別の問題です。)