2011-01-26 3 views
1

이 코드는 괜찮습니까?std :: string 생성자를 사용하는 const char *의 복사

void SomeClass :: foo(const char * _name) { 
    //name is of type const char * 
    name = std::string(_name).c_str(); 
} 

는 스피는

내가 옛날 학교의 strcpy을해야 괜찮 확실하지가 노력처럼 보이지만?

+2

WTF o_O. 'const char *'를'std :: string'으로 변환하고'const char *'로 되 돌린다. 지구상의 무엇을 위해? – mingos

+0

@mingos : 문자열을 만들고'c_str() '을 추출하면 버퍼를 명시 적으로 할당하지 않아도 어떻게 든 복사를 수행 할 수 있다고 생각하여 임시 작업과 같은 작업의 범위와 수명에 대한 일부 불확실성으로 인해 영업 담당자가 질문을 게시 한 것으로 의심됩니다. strcpy를 호출하십시오. 그것은 초보자 C++ 프로그래머에게는 완벽하고 합리적이며 흔한 실수입니다. –

+0

@Marcelo : 좋아, 나는 그런 가능성을 고려하지 않았다. :) – mingos

답변

6

컴파일되고 정의되지 않은 동작을 일으키지 않기 때문에 괜찮습니다.

문장이 완료된 후 이름이 잘못된 메모리를 가리 키기 때문에 이 아닌 ok입니다.

name = std::string(_name).c_str(); 

이 문장의 끝에서 임시 std :: string이 삭제되고 c_str()의 메모리가 해제됩니다.

나는 오래된 학교 strcpy를해야합니까?

아니, 단지 표준 : : 문자열로 이름을 변경 :

void SomeClass :: foo(const char * _name) { 
    //name is of type std::string 
    name = _name; 
} 
2

당신이 name와 아무것도하지 않으면이 완벽하게 안전합니다. 그렇지 않으면 나중에 임의의 지점에서 실패 할 것입니다. c_str() 멤버 함수에 의해 반환 된 C 스타일 포인터는 임시 std::string이 존재하는 한 (그리고이 경우에는 변경하지 않은 한) 변경 될 수 있습니다. 둘러싸는 블록 범위가 종료 되 자마자 임시가 파괴되고 name을 사용하면 황혼 지대가됩니다.

다른 사람들이 제안했듯이 namestd::string으로 설정해야합니다. 또는 char *으로 머무를 필요가 있다면 name = strdup(_name)으로 쓸 수 있습니다.

3

나중에 사용하는 것은 좋지 않습니다. 임시 메모리가 사용되는 즉시 메모리를 해제 할 수 있습니다. 문자열을 멤버로 사용하지 않는 이유는 무엇입니까? 그렇다면 메모리 관리에 대해 걱정할 필요가 없습니다.

1

이 경우 임시 개체를 만들어 포인터에 할당합니다. 함수를 떠날 때이 객체는 파괴되고 포인터는 아무데도 가리키고 있습니다. 메모리가 아직 덮어 쓰여지지 않아 작동하지 않을 수 있습니다. 하지만이 문제를 피하려면 strcpy를 사용해야합니다.

+0

임시 개체는 함수의 끝 부분이 아니라 전체 식의 끝에서 삭제됩니다. –

0

나는 strcpy에 투표합니다. 왜 단순한 일을 복잡하게 만드나요?

또는 더 나은 - 나중에 분명히 사용해야 할 것이므로 std::string으로 변환하지 말고 그냥 나중에 사용하십시오. 모두 char *을 잊어 버리시겠습니까?

관련 문제