내 프로그램 중 하나에서 const char*
.
다음과 같은 구조가 있다고 가정 해 보겠습니다.
struct Foo
{
const char* server;
const char* name;
};
내 상위 수준의 응용 프로그램은에만 처리 std::string
되므로 포인터를 std::string::c_str()
다시 가져 오기 const char*
위해을 ( 를) 사용 하려고 생각했습니다 .
그러나 수명은 c_str()
무엇입니까?
정의되지 않은 동작에 직면하지 않고 이와 같이 할 수 있습니까?
{
std::string server = "my_server";
std::string name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
// We use foo
use_foo(foo);
// Foo is about to be destroyed, before name and server
}
아니면 결과 c_str()
를 다른 곳에 즉시 복사해야 합니까?
감사합니다.
답변
c_str()
(가) 경우 결과가 유효하게 std::string
파괴 또는 문자열의 비 CONST 멤버 함수가 호출되는 경우. 따라서 일반적으로 보관해야 할 경우 복사본을 만들고 싶을 것입니다.
귀하의 예제의 경우 c_str()
해당 범위 내에서 문자열이 수정되지 않기 때문에의 결과 가 안전하게 사용되는 것으로 보입니다 . (그러나, 우리는 모르는 use_foo()
또는 ~Foo()
그 값으로 일을 할 수있는, 그들은 다른 곳에서 문자열을 복사 할 경우, 그들은 진정한해야 사본을 , 그냥 복사하지 char
포인터를.)
답변
기술적으로 코드는 괜찮습니다.
그러나 당신은 코드를 모르는 누군가를 위해 쉽게 깨뜨리는 방식으로 작성했습니다. c_str ()의 경우 유일한 안전한 사용법은 매개 변수로 함수에 전달할 때입니다. 그렇지 않으면 유지 보수 문제가 발생합니다.
예 1 :
{
std::string server = "my_server";
std::string name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
//
// Imagine this is a long function
// Now a maintainer can easily come along and see name and server
// and would never expect that these values need to be maintained as
// const values so why not re-use them
name += "Martin";
// Oops now its broken.
// We use foo
use_foo(foo);
// Foo is about to be destroyed, before name and server
}
따라서 유지 관리를 위해 다음 사항을 명확히하십시오.
더 나은 솔루션 :
{
// Now they can't be changed.
std::string const server = "my_server";
std::string const name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
use_foo(foo);
}
그러나 const 문자열이 있으면 실제로 필요하지 않습니다.
{
char const* server = "my_server";
char const* name = "my_name";
Foo foo;
foo.server = server;
foo.name = name;
use_foo(foo);
}
확인. 어떤 이유로 그들을 문자열로 원합니다
. 호출에서만 사용하지 않는 이유 :
{
std::string server = "my_server";
std::string name = "my_name";
// guaranteed not to be modified now!!!
use_foo(Foo(server.c_str(), name.c_str());
}
답변
다음 중 하나가 해당 string
개체에 발생할 때까지 유효 합니다.
- 개체가 파괴되었습니다
- 개체가 수정 됨
s가 복사 된 string
후 호출 되기 전에 해당 개체 를 수정하지 않는 한 코드에 문제가 없습니다 .c_str()
foo
use_foo()
답변
c_str ()의 반환 값은 동일한 문자열에 대해 상수가 아닌 멤버 함수를 다음에 호출 할 때까지만 유효합니다.
답변
에서 const char*
반환 된 c_str()
은 std::string
객체에 대한 다음 non-const 호출까지만 유효 합니다. 이 경우 당신 std::string
은 여전히 일생 동안 범위에 있고 Foo
foo를 사용하는 동안 문자열을 변경하는 다른 작업을 수행하지 않기 때문에 괜찮습니다 .
답변
문자열이 파괴되거나 수정되지 않는 한 c_str () 사용은 괜찮습니다. 이전에 반환 된 c_str ()을 사용하여 문자열을 수정하면 구현이 정의됩니다.
답변
완전성을 위해 다음 은 cppreference.com 의 참조 및 인용입니다 .
에서 얻은 포인터
c_str()
는 다음에 의해 무효화 될 수 있습니다.
- 문자열에 대한 상수가 아닌 참조를 표준 라이브러리 함수에 전달하거나
- 온 비 const 멤버 함수 호출
string
을 제외한,operator[]
,at()
,front()
,back()
,begin()
,rbegin()
,end()
와rend()
.