2016-07-25 13 views
6

나는 다음과 같은 C++ 코드에 대한 조금 혼란 스러워요 :초기화

#include <iostream> 

using namespace std; 

void test(const string& str) 
{ 
    static const char * const c = str.c_str(); 
    cout << c << endl; 
} 

int main(int argc, char* argv[]) 
{ 
    test("Hello"); 
    test("Nooo"); 
    return 0; 
} 

변수 c 이후 staticconst로 선언이 한 번만 초기화 할 수 있어야하고 초기 값을 유지 프로세스가 완료 될 때까지? 이 논리에 따르면, 나는 다음과 같은 출력 기다리고 있었다 :

Hello 
Hello 

을하지만 내가 가지고 : 변수 c의 값이 두 기능 사이에 수정 된 이유

Hello 
Nooo 

당신이 명확하게 할 수조차 불구하고 호출 변수가 const입니까?

답변

14

프로그램에 정의되지 않은 동작이 있습니다.

당신이 test-"hello"을 통과

는 임시 std::string 객체가 생성되고, 해당 문자열 c에서 (문자열 개체의 데이터에 단지 포인터 인)로 구성된다.

함수 호출이 끝나면 임시 std::string 개체가 삭제되고 c은 매달린 포인터가됩니다. 다시 정의되지 않은 동작입니다.

두 번째 임시 std::string 개체의 데이터는 첫 번째 것과 완전히 동일한 메모리 주소이므로 c은 해당 데이터를 가리 킵니다. 이는 어떠한 보증도 아닙니다.

+0

사실 그것은 정의되지 않았습니다. ** Dereferencing ** 정의되지 않았습니다. 역 참조 할 때 항상 유효한 주소를 가지므로 유효한 프로그램입니다. – StoryTeller

+3

@StoryTeller,'cout << c << endl;은 포인터를 역 참조합니다. –

+1

@StoryTeller 출력 연산자는 역 참조를 사용합니다. –

1

결과가 다를 수 있으므로 코드에 정의되지 않은 동작이 있습니다. UB는 test("Hello");이라는 호출이 정적 로컬 변수에 할당하는 임시 변수를 만들기 때문에 발생합니다. 이 임시는 호출이 끝난 후에 소멸되므로 테스트 함수의 포인터가 매달려 있습니다. 당신이 그것을 사용하는 경우 당신은 정의되지 않은 동작을합니다.

메모리 관리자가 동일한 메모리 영역을 다시 사용할 수 있으므로 결과에 Hello와 Nooo가 표시 될 수 있습니다.

관련 문제