2016-03-28 53 views
0

私はオブジェクトの所有権と考えています。私の目標は、JSON-RPCメッセージを作成することです。私が下位レベルで達成したいのは、オブジェクトの配列です。各オブジェクトは1つのオブジェクトerrorを持っています。その内側のerrorオブジェクトを除いて、すべてうまくいっています。おそらくrapidjsonの所有権が失われたために出力が壊れています:: Document :: Allocator

以下、私のコードの出力を見つけることができます。ご覧のとおり、error.messageは最初の8文字がnull文字に置き換えられています。予想される出力はInternal error: Don't know what happenedです。すべてのオブジェクトが作成され、ループ内の配列に追加されているので

[{"error":{"code":-32603,"message":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 error: Don't know what happened"},"jsonrpc":"2.0","id":null}] 

、範囲はすべての繰り返しの後に失われたので、私はそれが所有権に関係しているという考えを持っています。おそらくsomething like this?私は考えることができるすべてについて試しました。errorのループのオブジェクトに対してDocumentとを作成し、moveの代わりにコピーを使用してすべてのオブジェクトを構築しましたが、ここではちょっと立ち往生しています。誰でも内部のerrorオブジェクトの所有権を管理するのを助けることができますか?

ありがとうございます!


マイコード:

void MessageCenter::write_rpc_response(network::Session& session, 
     const std::vector<RPCResponse>& rpc_responses) 
{ 
    rapidjson::Document json_responses; 
    rapidjson::Document::AllocatorType& alloc = json_responses.GetAllocator(); 
    json_responses.SetArray(); 

    std::vector<RPCResponse>::const_iterator iter; 
    for (iter = rpc_responses.begin(); iter != rpc_responses.end(); iter++) 
    { 
     rapidjson::Document resp; 
     resp.SetObject(); 

     // Create error object, based on std::map 
     struct { int64_t code = 0; std::string message = ""; } error; 
     error.code = -32603; 
     error.message = "Internal error: Don't know what happened"; 

     // Create JSON object, based on the error object 
     rapidjson::Value data_object(rapidjson::kObjectType); 

     data_object.AddMember("code", 
       rapidjson::Value(error.code).Move(), alloc); 
     rapidjson::Value error_message(error.message.c_str(), 
       error.message.length()); 
     data_object.AddMember("message", error_message.Move(), alloc); 

     resp.AddMember("error", data_object.Move(), alloc); 

     // Add JSON-RPC version 
     rapidjson::Value jsonrpc_version(iter->jsonrpc.c_str(), 
       iter->jsonrpc.length()); 
     resp.AddMember("jsonrpc", jsonrpc_version.Move(), alloc); 

     // Add id: null if 0, int otherwise 
     if (iter->id == 0) { 
      resp.AddMember("id", rapidjson::Value().Move(), alloc); 
     } 
     else { 
      resp.AddMember("id", rapidjson::Value(iter->id).Move(), alloc); 
     } 
     json_responses.PushBack(resp, alloc); 
    } 

    // Write to the session 
    rapidjson::StringBuffer buffer; 
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); 
    json_responses.Accept(writer); 
    session.Write(buffer.GetString()); 
} 
+0

すべての 'c_str()'呼び出しは、スコープの外に出るオブジェクトの内部へのポインタを抽出します。また、匿名の 'struct'が必要ですか? –

+0

@UlrichEckhardtありがとう、それは実際にスコープから外れた 'c_str()'の抽出されたポインタでした。私はいくつかのアロケータを追加し、再びうまく動作します。 :-)いいえ、私は必ずしもその構造体は必要ではありませんが、このコードは実際のコードを単純化したものですが、より複雑なコードではデータを構造化するのに便利かもしれないと思いました。どういうことなんですか? – Hefting

+0

私が尋ねる理由は、ここで質問する前に、人々が最初に最小限の例を抽出することになっているということです。だから私はそれが何らかの形で問題を実証することが不可欠かどうか疑問に思っていた。 –

答えて

0

文字列を構築するためのいくつかのAPIがあります

//! Constructor for constant string (i.e. do not make a copy of string) 
GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } 

//! Constructor for constant string (i.e. do not make a copy of string) 
explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } 

//! Constructor for copy-string (i.e. do make a copy of string) 
GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } 

//! Constructor for copy-string (i.e. do make a copy of string) 
GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } 

は、次のコードは、文字列定数のバージョンを使用:

rapidjson::Value error_message(error.message.c_str(), 
      error.message.length()); 

をしかし、それはっきりとです0は範囲外になります。 respDocumentである必要はありません、ちなみに

rapidjson::Value error_message(error.message.c_str(), 
      error.message.length(), alloc); 

:あなたは、コピー、文字列のAPIを使用する必要があります。これはちょうどValueになります。しかし、常に外部アロケータを使用すると、バグは発生しません。

+0

あなたの精巧な答えをありがとう、ミロ!今私はそれをはるかに良く理解しています。 RapidJSONで良い仕事を続けてください。とても感謝しています。 :-) – Hefting

関連する問題