2016-07-12 20 views
0

以下の関数では、httppp要求をネットワークカメラに送信するために、cpprestsdk(https://github.com/Microsoft/cpprestsdk)からhttp_clientを使用しました。以下の関数は、特定の要求が行われたときにおそらくlcmライブラリ(http://lcm-proj.github.io/)によって呼び出されるコールバックです。shared_ptrとnew演算子:どちらを使用するか

auto init_session_response = new init_session_response_t; 

ポインタを作成し、手動でちょうど機能を終了する前にそれを削除するには:

は、私が以前にnew演算子を使用していたライン11との問題を抱えていました。 しかし、私はのstd :: shared_ptrの使用を開始する場合、この問題が去っていきましたライン49

init_session_response->status_code = 
       ptz_camera::status_codes_t::OK; 

でpplxタスク継続中init_session_responseオブジェクトを変更しようとしたとき、私は、アクセス違反の例外が発生しました。誰かがshared_ptrを使って問題を解決した理由を私に説明することはできますか? http_client *もstd :: shared_ptrを使用して作成する必要がありますか?

あなたが違反アクセスエラーを取得すると、あなたが(例えば、いくつかの thenラムダに)あなたのコード内のいくつかの場所にポインタを削除している必要があります
1 void lcm_handler::on_init_session_req(const lcm::ReceiveBuffer* rbuff, 
2 const std::string& channel, 
3 const ptz_camera::init_session_request_t* req) 
4 { 
5  std::cout << "Received init session req on channel: " << channel << 
6  "; Camera: " << req->ip_address << std::endl; 
7 
8 auto ip_address = req->ip_address; 
9 
10 // Note use of std::shared_ptr 
11 auto init_session_response = make_shared<ptz_camera::init_session_response_t>(); 
12 
13 auto key_position = this->ip_client_map.find(ip_address); 
14 if (key_position == ip_client_map.end()) 
15 { 
16  std::cout << "Creating a new client for the ip: " 
17   << req->ip_address << endl; 
18 
19  wstring username = this->convert_to_wstring(req->username); 
20  wstring password = this->convert_to_wstring(req->password); 
21 
22  wstring main_uri = L"http://" + convert_to_wstring(ip_address); 
23  auto config = http_client_config(); 
24  auto login = credentials(username, password); 
25  config.set_credentials(login); 
26  config.set_timeout(std::chrono::milliseconds(500)); 
27 
28  http_client* client = new http_client(main_uri, config); 
29  std::cout << "Client created...\n"; 
30 
31  uri_builder uri = uri_builder(U("/") + uri_constants::stw_cgi). 
32   append_path(uri_constants::attributes_cgi).append_path(uri_constants::attributes); 
33 
34  auto request = uri.to_string(); 
35 
36  client->request(methods::GET, request) 
37   .then([this, ip_address, client, init_session_response] 
38    (pplx::task<http_response> request_task) -> pplx::task<wstring> 
39  { 
40   try 
41   { 
42    auto response = request_task.get(); 
43    if (response.status_code() == status_codes::OK) 
44    { 
45     std::cout << "Saving client..."; 
46     this->ip_client_map[ip_address] = client; 
47     std::cout << "success.\n"; 
48 
49     init_session_response->status_code = 
50     ptz_camera::status_codes_t::OK; 
51    } 
52 
53    else 
54    { 
55     cout << "GET request to client failed! HTTP Error: " 
56      << response.status_code() << std::endl; 
57 
58     init_session_response->status_code = 
59      ptz_camera::status_codes_t::ERR; 
60    } 
61 
62    return response.extract_string(); 
63   } 
64    
65   catch (const exception& e) 
66   { 
67    cout << "Caught exception: " << e.what() << endl; 
68    return create_task([e, this]() -> wstring 
69    { 
70     return convert_to_wstring(e.what()); 
71    }); 
72   }    
73 
74  }) 
75   .then([init_session_response, this](wstring response) 
76  { 
77   string n = this->convert_to_string(response); 
78   init_session_response->response_message = n; 
79  }); 
80 } 
81 
82 
83 else 
84 { 
85  string message = "Client for ip: " + req->ip_address + " already exists\n"; 
86  cout << message << endl; 
87  init_session_response->response_message = message; 
88  init_session_response->status_code = ptz_camera::status_codes_t::OK; 
89 } 
90 
91 this->lcm->publish(ptz_camera_channels::init_session_res_channel, 
92  init_session_response.get()); 
93} 
+3

'shared_ptr'と' new'は相互に排他的ではありませんが、 'make_shared'でそれらを一般的にそのまま保つことは良い方法です。 – chris

+0

'delete'と念頭に置いておくと、結果は瞬間的(多かれ少なかれ)です - オブジェクトは有効でなくなります。これは、オブジェクトを割り当てるプロシージャの外にある可能性のある 'delete'の後の値(キャプチャされた値としてアドレスを使用するラムダなど)を参照する必要があるコールバック/タスクを設定するときに関係します。 –

+0

なぜ動作しないのか理解してほしい場合は、*動作しないコードを投稿する方がいいでしょう。 – Galik

答えて

1

が、私はこれを言うことができないので、あなたは生のポインタを使用してコードを投稿しませんでしたライン。それはラムダに渡されたとき、それは価値で撮影しています、std::shared_ptrを使用して、それがuse_countを高め、init_session_responseが有効で問題を解決しlabmdaに破壊されないことを保証することで