2008-10-29 4 views
10

\0 - 끝난 문자열을 가리키는 char* p 있습니다. 예외적 인 방식으로 C++ string를 만드는 방법은 무엇입니까?char *에서 std :: string을 안전한 방법으로 만듭니다.

안전하지 않은 버전은 다음과 같습니다.

string foo() 
{ 
    char *p = get_string(); 

    string str(p); 
    free(p); 
    return str; 
} 

확실한 해결책은 쉽게 잡을 수있는 방법 일 것입니다.

답변

25

당신은 C++11 또는 Boost에서 shared_ptr을 사용할 수 있습니다 :이 다른 auto_ptr 또는 아무것도, 사용자 정의 Deleter가를 지정하는 즉 기능을 사용할 수 없습니다 shared_ptr의 매우 구체적인 기능을 사용

string 
foo() 
{ 
    shared_ptr<char> p(get_string(), &free); 
    string str(p.get()); 
    return str; 
} 

; 이 경우, 나는 deleter로 free을 사용하고 있습니다.

+0

, 네 것을 제외하고 우리가 일반적으로 부스트를 사용하지 않는,하지만 나는 이러한 클래스 나 자신을 만들 수 있습니다. 감사합니다 –

+0

그 예입니다. – Allbite

1

넵 - 스택 기반 풀기. 현대 C++ 디자인은 일반적인 솔루션을 가지고 있지만이 경우 당신은 상관없이 정리 객체가 범위를 벗어나 때 호출됩니다 표준 : : 문자열, 무료 (toFree)로 발생하는

struct Cleanup { 
     void* toFree; 
     Cleanup(void* toFree) : toFree(toFree) {} 
     ~Cleanup() { free(toFree); } 
    private: 
     Cleanup(Cleanup&); 
     void operator=(Cleanup&); 
}; 

을 사용할 수 없습니다.

1

음, p은 0 끝나는 문자열을 가리 키지 않습니다 get_string() 반환 NULL 경우; 그 문제는 여기에 있습니다. 0- 종료 C 문자열에 대한 포인터를 가져 오는 std::string 생성자가 NULL을 처리 할 수 ​​없기 때문에 NULL은 바나나가 수십개 인 것처럼 0으로 끝나는 C 문자열입니다. get_string()은 라이브러리 함수와 반대로 자신의 함수 인 경우

그래서, 어쩌면 당신은 NULL을 반환 할 수 있는지 확인해야합니다. 예를 들어 자신이 소유 한 상태임을 알기 때문에 찾은 것을 std::string 자체로 돌려 보낼 수 있습니다. 그렇지 않으면, 나는 (댓글에 마틴 뉴욕에 의해 제안) p 누설 할 수 있음을 보장하기 위해 도우미로 this answer에서 Cleanup를 사용하여이 작업을 수행 할 것 :

string foo() 
{ 
    const char* p = get_string(); 
    const Cleanup cleanup(p); 
    const std::string str(p != NULL ? p : ""); 

    return str; 
} 
+0

코드 외에도 컴파일되지 않습니다 (L ""보세요). 그것의 예외는 안전하지 않습니다. 당신은 p가 공개 될 것이라고 보증하지 않습니다. –

+0

아! 죄송합니다 - Windows CE 기반 장치 용으로 만 개발할 수 있습니다. 유니 코드 문자열 만 있으므로 코드를 작성할 때 'L'접두사가 내 척추에 충격을받습니다. 이 경우가 수정되었습니다. –

+0

휴! 이제 그 누출은 사라졌습니다. 그것을 지적 주셔서 감사합니다. –

0

우리는 일반적으로 이러한 경우에 ScopeGuard를 사용

string foo() 
{ 
    char *p = get_string(); 
    ScopeGuard sg = MakeGuard(&free, p); 
    string str(p); 
    return str; 
} 
3

예를 들어 어떤 예외가 예상됩니까?

많은 플랫폼 (Linux, AIX)에서 new 또는 malloc은 실패하지 않으며 메모리가 부족하면 os에 의해 앱이 종료됩니다.

이 링크를 참조하십시오 : What happens when Linux runs out of memory.

관련 문제