std :: string :: c_str () 수명이란 무엇입니까?
내 프로그램 중 하나에서 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);
}
OK. For some reason you want them as strings:
Why not use them only in the call:
{
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());
}
It is valid until one of the following happens to the corresponding string
object:
- the object is destroyed
- the object is modified
You're fine with your code unless you modify those string
objects after c_str()
s are copied into foo
but before use_foo()
is called.
Return value of c_str() is valid only until the next call of a nonconstant member function for the same string
The const char*
returned from c_str()
is only valid until the next non-const call to the std::string
object. In this case you're fine because your std::string
is still in scope for the lifetime of Foo
and you aren't doing any other operations that would change the string while using foo.
As long as the string isn't destroyed or modified, using c_str() is OK. If the string is modified using a previously returned c_str() is implementation defined.
For completeness, here's a reference and quotation from cppreference.com:
The pointer obtained from
c_str()
may be invalidated by:
- Passing a non-const reference to the string to any standard library function, or
- Calling non-const member functions on the
string
, excludingoperator[]
,at()
,front()
,back()
,begin()
,rbegin()
,end()
andrend()
.
참고URL : https://stackoverflow.com/questions/6456359/what-is-stdstringc-str-lifetime
'programing tip' 카테고리의 다른 글
Xcode 4에서 인덱싱을 비활성화하는 방법은 무엇입니까? (0) | 2020.09.06 |
---|---|
템플릿을 사용할 때 "해결되지 않은 외부 기호"오류가 발생하는 이유는 무엇입니까? (0) | 2020.09.06 |
SVN 개정 번호를 내 ASP.NET 웹 사이트와 어떻게 동기화합니까? (0) | 2020.09.06 |
0x 표기법을 사용하는 숫자는 무엇을 의미합니까? (0) | 2020.09.06 |
XML 요소에 대한 표준 명명 규칙이 있습니까? (0) | 2020.09.06 |