C의 포인터 사용중에서 궁금한게 생겼는데요..
글쓴이: 찬밥 / 작성시간: 금, 2005/04/22 - 9:46오후
얼마전.. C++
시험공부를 하다..
책(The C++ Programming Language - Stroustrup)을 봤는데요..
char *str = "something"; str[3] = 'a';
이런식으로 하면 에러가 난다더라구요..
그래서.. 직접해봤는데 컴파일시 에러는 나지 않고..
실행했을 때 무슨 오류인진 모르겠으나..
Quote:
AppName: cpp1.exe AppVer: 0.0.0.0 ModName: cpp1.exe
ModVer: 0.0.0.0 Offset: 00001032
이런 내용과 함께 에러가 납니다..
그래서 이번엔
char str[] = "something"; str[3] = 'a';
위 처럼 고쳐서 해봤더니.. 아무문제가 없더군요..
이게 왜 그런건가요??
Forums:
[code:1]char *str = "something"
char *str = "something"
에서 str의 내용을 바꾸면 안 됩니다.컴파일은 잘 되도 실행하면 제대로 안 되는 경우는 아주 많습니다. 원칙에 어긋나는 것을 하면 그래도 될 때도 있기는 한데 항상 잘 된다는 보장은 없습니다.
세벌 https://sebuls.blogspot.kr/
두 코드가 어떤 방식으로 동작하는지 이해하고 있어야 합니다.[co
두 코드가 어떤 방식으로 동작하는지 이해하고 있어야 합니다.
"something"이라는 내용의 문자열 상수를 만들고, str이 그것을 가리키게 합니다. "something"는 문자열 상수이므로 그 내용을 고칠 수 없습니다.
char형 배열 str을 "something"이라는 내용으로 초기화합니다. str의 크기는 "something"을 저장할 수 있는 크기로 자동 결정됩니다. str은 char형 배열이므로 당연히 그 안의 내용을 고칠 수 있습니다.
간단히 이야기하면 두개의 형이 다릅니다.char str[] 와 c
간단히 이야기하면 두개의 형이 다릅니다.
char str[] 와 char * str은 엄밀히 이야기하면 다른 타입입니다.
str[]는 포인터가 아니라 어레이죠.
그리고 포인터로 implicit conversion이 가능할 뿐입니다.
두 개는 또한 저장되는 위치또한 다릅니다.
보통 char str[] = "~~" 로 할당될때
~~는 스택에 저장이 됩니다. 스택은 쓰고 읽기가 가능합니다.
char * str = "~~" 에서 할당작업은 일어나지 않습니다.
위의 "~~"는 리터럴 상수로서 보통 데이터영역에 저장이 됩니다
이 데이터 영역은 보통 쓰기 금지가 되어있죠??
그래서 에러가 날겁니다.
잘 알지도 모르는 사람이 그냥 써봤습니다.
혹여 고수님들 틀린거 있으면 지적해주세요 ㅠ.ㅜ
C++, 그리고 C++....
죽어도 C++
아래 두 분 말씀이 정확합니다.하나는 데이터 영역이라 수정이 불가
아래 두 분 말씀이 정확합니다.
하나는 데이터 영역이라 수정이 불가하고, 하나는 스택 영역이라 수정이 가능합니다.
[code:1]char *s = "hello, world!&qu
보통은 code 영역에 잡히는게 아닌가요? 물론 이것도 구현에 따라 다르겠지만요.
진리를 나의 수준으로 끌어내리지 마라.
나를 진리의 수준으로 끌어올려라. - 배꼽 중에서
char *str="something";하면 "something"이라
char *str="something";
하면 "something"이라는 문자열은 컴파일하고 실행될때 메모리의
어딘가에 할당되어 있습니다..
만일 char str[2] 이렇게 하면 str이 잡힌메모리 번지+2 이곳을
참조하게 됩니다.. *(str+2)이렇게요..그럼 당연히 메모리
침범이 되어서 에러가 나겠죠...
변수 str에 할당된 메모리 번지에 +2번지가
더해져서 에러가 나는거겠죠...
[quote="dondek"][code:1]char *s = "
생각해보니 궁금해 져서 한번 해보았습니다.
위 코드를 gcc -c test.c로 하여 컴파일 해보았습니다.
그리고 그 결과를 objdump로 한번 떠 보았습니다
다음과 같더군요
이렇게 보면 잘 모를 것입니다.
그러나 Hello, World의 아스키 값을 적어보자면
48(H), 65(e), 6c(l), 6c(l)... 로 되고
저기 .rodata 세그먼트에 있군요 앞의 20은 스페이스가 되겠습니다. 결론적으로 이 Hello 패턴을 두개 찾을 수 있습니다
.rodata세그먼트에서요 :D
이 짓을 다 하고 보니 생각해보니까
strings라는 간편한 유틸리티가 있었는데 -_-;;
내가 멀 했나 하기도 싶고..
물론 이건 순전히 gcc 구현에 따른 것이기 때문에 절대적인
자료는 될 수 없겠지만, 요새 컴파일러들이
데이터 상수들과 코드를 섞어서 컴파일할것이라고 생각 되지는
않네요 ^^
C++, 그리고 C++....
죽어도 C++
소스코드내에 초기화 된 변수들의 내용은data 영역에 저장 됩니다.
소스코드내에 초기화 된 변수들의 내용은
data 영역에 저장 됩니다. 이영역은 read-only 영역입니다
그래서 고칠 수 가 없습니다
지역변수인 char *string 자체는 포인터 이지만
그것이 가르키고 있는 영역이 data 영역이라는 의미입니다
[code:1]#include <stdio.h>in
에서 abcd변수가 초기화 된 변수로서 data 영역에 저장된다고 알고 있는데... read only가 아니지 않습니까???
그리고... 스택에서
char *str = "string";
라고 하는건... 정확히 표현해서const char *str = "string";
이지 않습니까? 즉... 고칠 수 없는 문자열 포인터죠...[quote="박현우"][code:1]#include <stdi
^^ 잠시 착각하신거 같습니다.
advanced님께서 설명해 주셨지만
다시 설명하자면 abcd와 1234가 저장되는 위치가 틀립니다.
1234는 데이터 영역에 있고 abcd는 코드 영역에 있습니다.
1234는 readonly입니다.
두번째로 "string"은 const char * 형이 아닙니다.
제가 알기로는 C++에서는 const char[] 이고
C에서는 단순히 char * 라고 알고 있습니다 <- 확실치 않네요 C는 잘 몰라서 ^^ 혹시 틀렸다면 고수분들 지적을;;
C++, 그리고 C++....
죽어도 C++
[quote="ixevexi"] 이렇게 보면 잘 모를 것입니다.
objdump -s
==333
여친이 길르는 용..


[quote]에서 abcd변수가 초기화 된 변수로서 data 영역에
전 그래서 스택이니 힙이니 데이터영역이니 하는 설명방식을 싫어합니다. 단지 문자열 상수가 실은 수정불가능한 char형 배열이라는 점만 알면 되는데 굳이 컴파일러 내부 구현까지 들먹일 필요는 없지요.
문자열 상수는 배열입니다. char str[] = "str"과 같이 char형 배열을 초기화할 때 빼고는.
좀 더 정확히 얘기하자면
가 되겠죠.
Processor가 메모리 보호를 지원하기때문에.. 그렇겠죠제 개발환
Processor가 메모리 보호를 지원하기때문에.. 그렇겠죠
제 개발환경에서는 다됩니다. ㅠㅠ
arm without memory protection..
^^ be cool ~
http://fromdj.pe.kr
[quote="Anonymous"][quote]에서 abcd변수가 초
질문하신 분의 문제는 컴파일러 문제가 아닙니다...플랫폼의 문제입니다. 즉, 실행 환경에서 상수 문자열이 저장되는 메모리 공간이 readonly이기 때문에 발생한 에러입니다. 말씀하신 것과 같이 const type에 의한 문제하고는 약간의 차이가 있습니다. 제시하신 예처럼 const char [] 의 경우라면 단순히 type casting을 하게 되면 얼마든지 문자열의 내용을 바꿀 수 있지만 질문하신 분의 경우는 type casting으로 해결할 수 없습니다. 왜냐하면 문자열이 위치한 메모리 자체가 쓰기 금지 영역이기 때문입니다...상수 문자열의 포인터를 const char* 로 하는 이유는 바로 이러한 런타임 오류를 막기 위한 문법적인 조치라고 이해하는 것이 더 좋다고 생각합니다...
------------------------
http://agbird.egloos.com
[quote="Agbird"]질문하신 분의 문제는 컴파일러 문제가 아닙니
누구(또는 어느 것)의 문제냐고 굳이 따진다면 저는 컴파일러도 아니고 플랫폼도
아니고 원래 코드 자체라고 하겠습니다. 추상적인 언어 정의가 어떻게 구현되는지
아는 것도 좋겠지만, 그 이전에 언어의 정의를 올바르게 이해하는 것이 우선이라고
생각합니다. C 또는 C++에서 문자열 상수를 변경하는 결과는 정의되지 않는다
(undefined)라고 규정하고 있습니다. 이 경우 구현체는 나름대로 합당하다고
생각하는 행동을 선택할 수 있습니다. 바로 seg fault를 낼 수도 있고, 변경하려는
행위를 무시할 수도 있고, 실제로 문자열을 변경할 수도 있습니다. 물론 이렇게
정의되지 않는 결과를 유발하는 코드는 잘못된 것입니다.
const char[]를 캐스팅을 통해 변경하는 결과 역시 정의되지 않습니다.
즉 const로 정의된 개체를 변경하는 *모든* 행위는 잘못입니다.
저는 const char*로 하는 이유는 정의되지 않은 결과를 유발하지 않도록 하기 위한
조치라고 이해하는 것이 더 좋다고 생각합니다.
[quote="Agbird"]질문하신 분의 문제는 컴파일러 문제가 아닙니
doldori 말씀 처럼 코드가 문제인 것입니다.
많은 사람들이 구현 자체에 집중하고 있어서 문법적으로 틀린 코드에 대해서 관심을 가지고 있지 않군요.
안되어야 하는 이유는 논리적으로 잘못되었기 때문이고 그게 강제성이 없기 때문에 일부 컴파일러/인터프리터에서 제대로 작동이 되는 것입니다.
- 죠커's blog / HanIRC:#CN
..
잘 배워 갑니다.
댓글 달기