2011-08-22 2 views
12

저는 C++의 문자열에 상당히 초보적이어서 다음과 같은 패턴이 약간 엉망이 될 수 있습니다. 더 큰 시스템으로 통합 테스트를 시작하기 전에 필자가 작성한 코드를 검토하고 있습니다. 내가 알고 싶은 것은 그것이 안전한지 또는 메모리 누수가 발생하기 쉬운가하는 것입니다.메모리 누수로부터 안전한 C++ std :: string 객체를 반환하고 있습니까?

string somefunc(void) { 
    string returnString; 
    returnString.assign("A string"); 
    return returnString; 
} 

void anotherfunc(void) { 
    string myString; 
    myString.assign(somefunc()); 
    // ... 
    return; 
} 

내가 가진 이해는 returnString의 값이 새 개체 mystring에 할당 된 후 returnString 객체가 somefunc에 대한 호출을 해결의 일환으로 파괴된다는 것이다. myString이 범위를 벗어나게되면 미래의 어떤 시점에서 그것도 파괴됩니다.

일반적으로 myString에 대한 포인터를 somefunc()에 전달하고 myString 값에 직접 할당했지만 코드에서 조금 더 명확 해지기 위해 노력하고 있습니다 (부작용 함수 스타일에 덜 의존).

+0

첫 번째 함수에서 "return string ("A string ");" 같은 결과를 얻습니다. – luiscubal

+0

@luiscubal 이것은 문제를 설명하기위한 단순화 된 예입니다. – Stephen

+2

@luiscubal 심지어'return "std :: string은 c 문자열로 구성 가능하기 때문에"; "문자열은 괜찮습니다. – log0

답변

10

내가 이런 식으로 할당 선호 불구 예, (값)를 string이 방법을 반환하는 것이 안전하다 :

string myString = somefunc(); 

이 읽기 ​​쉽게, 그리고 또한 더 효율적입니다 (빈 문자열의 구성을 저장하고 다음 번 호출을 통해 assign으로 겹쳐 쓰게됩니다).

std::string은 자체 메모리를 관리하며 적절하게 작성자 및 할당 연산자를 작성하므로이 방법으로 문자열을 사용하는 것이 안전합니다.

2

예 (적어도 정상적으로는) 안전합니다. 거의 모든 합리적인 문자열 클래스의 가장 기본적인 기여 중 하나는 정상적인 할당, 반환 등이 "그냥 작동"하는 기본 값처럼 작동 할 수있는 능력입니다.

return returnString 

을 수행하여

7

예 당신은 문자열의 copy constructor를 호출한다.

myString.assign(somefunc() /*somefunc()'s return becomes temporary*/); 

이 차례로 할당 전달 및 할당에 의해 사용의를 수행하는 것입니다 : 어느 호출 표현의 장소 소요 * 임시 (일명를 rvalue)에 returnString의 사본 "somefunc()"를 수행 myString에 복사하십시오.

따라서 문자열의 복사본 생성자는 완전한 복사본을 보장하고 메모리 누수를 방지합니다.

* 실제 복사본이거나 그렇지 않을 수도 있습니다. 복사 생성자의 동작은 구현에 따라 다릅니다. 일부 문자열 라이브러리는 실제로 필요할 때까지 복사를 방지하기 위해 내부 부기가있는 copy-on-write를 구현합니다.

+1

사실 깊은 복사가 수행되는지 여부는 사용중인 특정 표준 라이브러리 구현에 따라 다릅니다. GCC는 COW를 사용하므로 복사 생성자는 단순히 카운터를 증가시키는 것을 의미합니다. –

+0

@Matthieu 좋은 지적 나는 내 대답을 분명히했다. 감사. –

5

값으로 문자열을 반환하기 때문에 완전히 안전합니다. 여기서 문자열은 참조가 아닌 "복사 됨"입니다. std::string &을 반환하는 경우 매달린 참조가 있으니 잘못했을 수 있습니다. 일부 컴파일러는 반환 값 최적화을 수행 할 수도 있습니다.이 경우 반환시 문자열을 복사하지 않습니다. 자세한 내용은 this post을 참조하십시오.

0

당신이 말한대로 returnString 문자열이 somefunc 안에 만들어지고 함수가 반환 될 때 복사본이 반환됩니다. 이것은 완벽하게 안전합니다.

myString에서 somefunc (포인터를 사용하지 않음)에 대한 참조를 제공하고 싶습니다. 그것은 완벽하게 명확 것이다

void somefunc(string& myString) { 
    myString.assign("A string"); 
} 

void anotherfunc(void) { 
    string myString; 
    somefunc(myString); 
    // ... 
    return; 
} 
+1

이것은 컴파일러가 일반적으로 수행하는 반환 값 최적화를 우회하므로 개선되지 않습니다. –

+0

@Bo Persson 성능 개선에 대해 언급 한 적이 없습니다. – log0

+0

'당신이 원하는 것은 ... ... 왜 그렇게 말합니까? 그가하는 일보다 코드에 별다른 이점이 없습니다. –

관련 문제