2014-01-22 2 views
0
const std::string makeUniqueName() 
{ 
    srand(time(NULL)); 
    std::string s;                            
    std::generate_n(const_cast<char*>(s.c_str()), 10, RndGenerator()); 
    return s; 
} 

이 코드는 안전한가요? 컴파일러는 경고 메시지를보고하지 않습니다.이 코드는 안전한가요?

+3

아니요, 물론 아닙니다. 'generate_n'은 데이터를 쓸 곳이 필요합니다. – juanchopanza

+7

'const_cast'를 사용하여 자신을 발견했지만 그 이유를 이해하지 못한다면 그 대답은 거의 확실합니다. "아니오!" – benjymous

+1

쓰기 가능한 메모리에'.c_str()'을 사용하지 말고, 반복자를 사용하십시오. 그리고 ** const 값으로 ** 돌아 오지 마십시오. – Griwes

답변

3

코드는 아직 할당되지 않은 메모리에 기록함으로써 정의되지 않은 동작을 호출합니다. 해당 문자 (std::string s(10, 0);)에 충분한 공간이있는 문자열을 구성하고 std::begin(s)generate_n으로 전달하거나 std::back_inserter을 사용하십시오.

는 또한, const 포인터에 const_cast를 사용하여, 당신은 (그것이 정의되지 않은 동작입니다에 작성 후 const 객체에서 const을 제거하고) 다시 정의되지 않은 동작을 호출.

또한 const 값으로 반환하지 마십시오. 이동 의미를 금지하고 이 아닌이 필요합니다.

+0

이 함수의 전체 구현은 사용자가 가지고있는 제안을 사용하는 것과 어떻게 다릅니 까? –

+0

@MagnusHoff, 음, OP는 자신의 코드의 일부를 내 제안에서 나온 코드로 대체하는 작업에 대처해야한다고 생각합니다. 'back_inserter'에 대한 예제를 읽거나 std :: begin()을 호출하면 로켓 과학이 아닙니다. . – Griwes

2

글자를 쓰고 싶다면 문자열을 저장할 공간이 필요합니다.

아마도 더 중요하게는 const_castc_str()에 사용해야합니다. c_str()이 가리키는 메모리는 수정할 수 없습니다. 그대로, 코드는 정의되지 않은 동작을 호출합니다.

코드가 호출 될 때마다 코드가 반드시 고유 한 이름을 생성 할 필요는 없습니다. 아주 가깝게 두 번 호출 할 수 있으며 time(NULL)은 두 호출에 대해 동일한 것을 반환합니다. 또는 다른 씨드라도 RNG가 동일한 값을 반환한다는 것을 알 수 있습니다.

2

아니요, 안전하지 않습니다!

문자열에 아무 것도없고 10 개의 항목을 추가하려고합니다. 다음과 같이 문자열에 공간을 예약해야합니다.

std::string s(10,' '); 

직접 작성하려면 시작을 클릭하십시오.

+0

문자열의 메모리가 미리 할당 된 경우에도 c_str() 포인터를 사용하여 문자열에 쓰거나 쓰는 것은 나쁜 습관입니다! – benjymous

2

절대 안전하지 않습니다. C++ 표준은 c_str이 가리키는 값의 수정을 명시 적으로 금지합니다. 컴파일러는 const_cast 때문에 불평하지 않지만 여전히 잘못되었습니다.

관련 문제