2017-05-09 14 views
0

아래의 기능은 작동하지만, 나에게는 매우 나쁜 냄새가 난 것 같습니다.C++ 몇개의 istream 포인터와 refferecnes와 리팩토링

내 프로젝트는 HTTP를 통해 기기와 통신하며, 다이제스트 인증을 사용하는 일부 URL,없는 일부 페이지가 있습니다. 일부 URL은 압축 된 상태로 압축되며 일부는 압축되지 않습니다. 그래서 내 함수는 istream을 얻는 3 가지 다른 방법이 있습니다. 그리고 함수의 맨 아래에있는 한 곳에서 istream을 읽어야합니다. 하지만 다른 좋은 질문에 대답했다 C++ variable visable scopes and strems,이 경우에는 포인터가 좋지 않습니다.

그리고이 코드에서는 동적 객체를 만드는 경우가 있습니다.

Poco::InflatingInputStream* inflater = new Poco::InflatingInputStream(*respStreamPtr); 

그리고 이것은 메모리 누출 경로입니까? 새로운 문없이 인플레이터를 만드는 경우

* respStreamPtr는 경우 블록 범위를 벗어난 데이터가 없습니다.

그래서이 코드를 올바른 방법으로 리팩토링하는 방법에 대해 조언 해주십시오. 당신이 new을 사용할 때마다 같은 메모리 누수 될 것입니다

std::ostream& requestStream = session->sendRequest(request); 
    istream* respStreamPtr; 
    respStreamPtr = &session->receiveResponse(response); 
    if (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED) 
    { 
     credentials->authenticate(request, response); 
     session->sendRequest(request); 
     respStreamPtr = &session->receiveResponse(response); 
    } 
    if (response.has("Content-Encoding") && response.get("Content-Encoding") == "deflate") { 
     Poco::InflatingInputStream* inflater = new Poco::InflatingInputStream(*respStreamPtr); 
     respStreamPtr = &std::istream(inflater->rdbuf()); 
    } 
    std::ostringstream stringStream; 
    stringStream << respStreamPtr->rdbuf(); 
    responseBody = stringStream.str(); 

답변

0

예, 당신이 delete

그러나, 당신이 선언 된 것 범위의 inflater 변수 밖에 사용하지 않습니다 새로운 객체를 생성합니다 그래서 현재 다른 코드를 수정하지 않고 멋지게 삭제할 방법이 없습니다. 간단한 수정을 위해 코드 상단에 Poco::InflatingInputStream* inflater = nullptr;을 선언 한 다음 끝에 코드를 삭제하면됩니다.

난 강력하게 (먼저 기초를 학습하지 않고 있지만) C++에서 제대로 메모리를 관리하는 방법에 대한 독서, 심지어 스마트 포인터에서 보라는 권유를 줄

마시고 실제로 많이 수행 기능이 있습니다 당신이 뭘 하려는지, 그래서 귀하의 예를 쉽게 응축 될 수있다 (면책 조항 : 검증되지 않은) :

session->sendRequest(request); 
auto& responseStream = session->receiveResponse(response); 
if (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED) 
{ 
    credentials->authenticate(request, response); 
    session->sendRequest(request); 
    responseStream = session->receiveResponse(response); 
} 
if (response.has("Content-Encoding") && response.get("Content-Encoding") == "deflate") 
{ 
    Poco::InflatingInputStream inflater(responseStream); 
    StreamCopier::copyStream(inflater, responseStream); 
} 
responseBody << responseStream; 
+0

'변화 마시고 :: InflatingInputStream의 *의 인플레이터 추천, 마시고 :: InflatingInputStream의 *의 인플레이터 = nullptr'에',' 그래서 사용하지 않으면 마지막에 삭제하는 것이 안전하다는 것을 알 수 있습니다. – user4581301

+1

예, 감사합니다. nullptr에 대한 검사가 삭제되기 전에 추가로 추정됩니다. –

+0

Jnny Paton의 코드가 작동하지 않습니다. 두 번째 과제 대신에 첫 번째 오류 :'responseStream = session-> receiveResponse (response);'마사지를 사용하면 ** "참조 할 수 없습니다"**. 그리고 내가 옳은 원인인지 이해할 수 있기 때문에 responseStream은 참조입니다. 'StreamCopier :: copyStream (inflater, responseStream);의 두 번째 오류 메시지가있는 : ** "std :: istream"유형의 값으로 초기화 할 수 없습니다. ** – greenif