2016-07-12 5 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; 

포인터를 만들고 수동으로 단지 기능을 종료하기 전에 삭제하기 :

은 내가 이전에 새로운 연산자를 사용하여 한 라인 (11)에 대한 문제가 있었다. 하지만 표준 : : 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을 사용하여 만들어야합니까? 당신이 위반 액세스 오류가 발생하는 경우

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

, 당신은 (예를 들어, 일부 then 람다에서) 코드에서 어떤 장소에서 포인터를 삭제해야합니다,하지만 당신은 내가 말할 수 없다 원시 포인터를 사용하여 코드를 게시하지 않았다 선. 이 람다로 전달 때 그것이 use_count을 증가 init_session_response 유효하고 문제를 해결 labmda에 파괴없는 것을 보장 그래서,이 값에 의해 촬영 된 것, std::shared_ptr 사용함으로써

.