문제

이 코드는 MS Visual Studio에서 이상하게 행동합니다.

char *s = "hello";
s[0] = 'a';
printf(s); 

최적화가 켜진 릴리스 빌드에서 S [0] = 'A'및 "Hello"를 인쇄합니다. 최적화 나 디버그 빌드에서는 액세스 위반으로 충돌합니다.
이 동작은 C ++ 표준을 준수합니까? 제 생각에는 컴파일러는 문자 그럴에 대한 지속적인 참조 만 허용해야합니다.

const char *s = "hello";

편집하다: 나는 그것이 왜 이런 식으로 작동하는지 알고 있습니다. 왜 메모리 전용 메모리를 읽기 위해 비 Const 참조를 만들 수 있는지 이해하지 못합니다.

도움이 되었습니까?

해결책

이 코드가 처음에 허용되는 이유 (선언이 유형이어야하는 대신 char const*)은 이전 C 코드와의 호환성입니다.

엄격한 모드의 대부분의 최신 컴파일러는 a가 발행됩니다 경고 그러나 위의 코드는!

다른 팁

아니요, 컴파일러의 버그가 아닙니다. 당신이 쓸 때 :

char* s = "hello";

문자열 상수 "hello" 읽기 전용 섹션에 배치되며 수정하려는 경우 예외가 생성됩니다. (C ++ 예외가 아닌 OS 예외).

쓰기 쉽게하려면 배열을 사용해야합니다.

char s[] = { 'h', 'e', 'l', 'l', 'o', 0 };

또는 실제로 포인터가 필요한 경우 배열을 가리 키십시오.

char _s[] = { 'h', 'e', 'l', 'l', 'o', 0 };
char* s = _s;

나는 const 포인터가 문자열 리터럴로 초기화되도록 허용하는 것에 대한 당신의 요점을 볼 수 있지만, 나는 그것이 깨질 것이라고 생각합니다. 많은 기존 코드.

C ++ 컴파일러는 표준 당 메모리 페이지 만 읽기에 문자열 리터럴을 할당 할 수 있다고 생각합니다.

*s가 문자열 상수의 메모리 주소를 가리키고 있기 때문에 변경할 수 없기 때문에 작동하지 않습니다.

실제로 최적화로 컴파일 될 때 액세스 위반을받지 못하는 것에 대해 조금 놀랐습니다.

char *s = "foo";

까다로운 조랑말입니다. 실제로 이것이 실제로 읽기 전용 문자열이라고 말하지 않습니다. 동료가 다른 문자열을 작성하게 할 수 있기 때문에 이것은 다음과 같습니다.

char *t = "foo";

이제 컴파일러는 유용한 최선을 다하면 하나의 사본 만 유지할 수 있으며 하나를 변경하면 많은 당신과 당신의 친구를 행복하게하기 위해서만 일합니다. 그래서 그렇게하려고하지 않습니다. 이것은 표준에서 찾을 수있는 것입니다. 무엇을하고 있는지, 당신이하고있는 일이 UB를 불러 일으킨다.

즉, 당신이 당신의 길을 가졌다면 표준위원회의 가난한 사람들이 감당할 수없는 많은 레거시 코드를 깨뜨릴 것입니다. 그래서, 당신은 있습니다.

기억하십시오 const 우리는 하루에 태어나지 않은 평온한 사용에 대해 유죄입니다. Bjarne은 많은 영혼을 찾는 일을했으며 다른 사람들도 그것을 넣을 것인지 아닌지를 많이 사용했습니다. 사실, 그는 읽기 전용 및 쓰기 전용 변수를 가지고 있다는이 훌륭한 아이디어를 가지고 있었지만 다른 날에 그 이야기를 저장하겠습니다.

그리고 마지막으로, 우리가 돌봐야 할 좋은 친구 C가 있습니다. 그래서 ...

다른 사람들이 말했듯이 문자열 문자를 수정할 수는 없습니다. 또한 코드에서 컴파일러 경고를받지 않는 이유도 궁금합니다. 컴파일러는 메모리 만 읽기 위해 쓰려고한다는 것을 확실히 알 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top