"어쩌구"하는 문자열은 임시로 어떤 (??) 공간에 저장되는데,
그 주소가 무슨 성격인지는 저도 정확히는 모르겠습니다만,
그 주소가 p에 저장된다고 합니다.
어쨌든 공식적인 사용 방법이 아님에는 틀림이 없다고 했던 것 같습니다.
정확히 하려면 그 어떤 (??) 공간의 “값”을 strcpy를 통해서
정식으로 복사하는 것이 바람직하다고 했던 것 같습니다.
메모리는 보통 code영역, data영역, heap, stack 이렇게
4 가지 종류로 나뉜다고 알고 있습니다.
char *p="string";
이렇게 코딩을 하면, "string"에 해당하는 부분은
code영역에 들어갑니다. (gcc -S 해 보시면 쉽게 알 수 있습니다.)
code영역에 들어가기 때문에 read only이고, 따라서
문자열을 고치려(즉 쓰려) 시도하면 segment fault를 냅니다.
char *p = (char*)malloc(sizeof(char)*N);
이렇게 해서 strcpy/memcpy등의 함수를 이용해 카피하는 것은
heap영역에 메모리를 잡기 때문에 read/write가 모두 가능하며
따라서 문자열을 마음대로 고칠 수 있습니다.
그 차이를 가지고 공식적인 사용이다 아니다 이렇게 말할 수는 없습니다.
그렇다면 printf("My name is %s",namestr) 이 코드도
"My name is %s"가 code 영역에 저장되게 되는데, "공식적으로"
잘못 사용하고 있는 것인가요?
char *p="something";
이렇게 하면 문자열을 마음대로 고칠 수 없다는 것을 아는 것으로
충분하며, readonly라는 것을 안다면 아무 문제 없습니다.
아래에 지적하신 분들 말씀대로
문법상 오류는 없는 걸루 압니다.
p = "hi";
라고 하는 의미는 p가 문자열 "hi"의 주소를 가리키겠다는, 포인터 문법
에 전혀 문제없는 방식 아닌가요.
문자열 "hi"는 code영역에 올라가는데, 소스코드가 code영역에 쫘악 올라
갈때, 그때 저 "hi"라는 문자열이 소스코드안에 포함이 되겠죠. "hi"라는
문자열이 다른 메모리 영역에 따로 저장되는게 아니라서 포인터 p는 code
영역의 "hi"라는 문자열의 주소를 그대로 가리키게 됩니다. 물론,
readonly구요.
그리구, heap영역상에 메모리 잡아도 다른 메모리 할당에 의해 덮어져서
사라지거나 수정되는 경우는 없습니다. 잡아놓은 메모리 이상으로 사용하
지 않는다면요. 또, 엄밀히 말해서 배열을 쓴다고 해서 안전한 것도 아닙
니다. 배열은 해당함수의 stack 영역에 잡히는데 stack역시 지정 공간 이
상으로 쓰기가 가능하기 때문입니다. (stack overflow라고도 하죠)
엄밀히 말해서, 그건 프로그래머의 책임이죠.
그건 틀리는 내용 입니다.
char *p[5]; -> 이건 포인터 5개를 저장할 포인터 배열이고.
char a[5][10] -> 이건 그냥 2차원 배열 입니다.
char a[5][10] -> char a[50] 이렇게 쓰는거랑 비슷합니다.
단지 편리하게 사용 할 수 있게 2차원을 쓰는거죠..
추가질문) 포인터와 배열....
결국
char *p[5] 와
char p[5][10] 이렇게 하는 것을 비교하는 것과 같은 경우가 되겠군요
Re: 포인터와 배열....
char *p;
p = "hi";
위의 문장은 에러가 납니다.
p는 포인터이고 "hi"는 문자열입니다.
포인터에 문자열을 집어넣기 때문이죠
당연히 p = "hi"라고 하면 에러가 나죠.
Re^2: 포인터와 배열....
char *p;
p="HI";
가 에러가 나다뇨?
착각하신것 같은데요 ^^
지나가다가 wrote..
char *p;
p = "hi";
위의 문장은 에러가 납니다.
p는 포인터이고 "hi"는 문자열입니다.
포인터에 문자열을 집어넣기 때문이죠
당연히 p = "hi"라고 하면 에러가 나죠.
Re^3: 포인터와 배열....
그거.. 되긴 되는데요...
ANSI표준되로라면 틀린겁니다.
되긴 된다라.. gcc에서는 어떤지 모르겠네요 ^^;
Re^4: 포인터와 배열....
gcc 에서는 잘되네요.
gcc 에서 -ansi 옵션을 주고 해도
어떤 경고 메세지도 않나오네요.
gcc 에서 -ansi 옵션을 주면 ANSI 로 컴파일 하는걸로 알고 있는데,
맞는지 답변 좀 부탁드립니다.
Re^5: gcc에도 에러입니다.
p에 "hi"라는 주소값이 들어간것이지,
실제로 문자열 "hi"가 들어간게 아닙니다.
이건 진짜 고급 문제인데.....
Re^6: gcc에도 에러입니다.
주소값이 아닌 포인터도 있남?
아님, 포인터에 문자열을 넣을수도 있다는 이야기?
그리고 제가 테스트 해 봤는데
gcc 에서 에러 안남니다.
지나가다가 wrote..
p에 "hi"라는 주소값이 들어간것이지,
실제로 문자열 "hi"가 들어간게 아닙니다.
이건 진짜 고급 문제인데.....
Re: 포인터와 배열....
;char *p;
;p = "hi";
;와
;char a[10];
;strcpy(a, "hi");
;의 차이점은요.?
1번 char *p = "hi"; 는 이후 p가 다른 주소를 가리키게 할 수는 있지만
p의 내용 "hi"를 "ab" 등으로 바꿀 수는 없습니다.
반면 2번 char a[10]은 1번과 정반대로서
a가 다른 주소를 가리키게 할 수는 없지만 내용은 바꿀 수 있습니다.
만일 char *p, xxx[10];
p = xxx;
이렇게 해 놓고서 p의 내용을 바꿀 수 있지 않냐고 따지지는 마세요.
(치사하잖아요? ㅋㅋㅋ)
;제가 보기엔, 배열로 선언하는 것은 배열을 할당 받는 것이기 때문에 안전하고
;포인터로 사용한 것은 임의의 주소 공간에 쓴것이기 때문에 다른 데이타가 나중에
;덮어 쓸 위험이 있지 않나요?
전혀 위험하지 않습니다.
아래 문법이 맞느니 틀리느니 하는 내용에 대해서는
전혀 틀리지 않다가 당연히 맞겠죠?
지나가다님이 급히 지나가느라 잘못 봤나 봅니다. ㅋㅋㅋ
저번에도 논란이 되었던 문제가 아닙니까?
저도 관심있게 봤던 문제인데,
(제가 잘 모르거든요 -_-)
그 때 요지가 대략 이랬던 거 같습니다.
char *p;
p = "어쩌구";
하면,
"어쩌구"하는 문자열은 임시로 어떤 (??) 공간에 저장되는데,
그 주소가 무슨 성격인지는 저도 정확히는 모르겠습니다만,
그 주소가 p에 저장된다고 합니다.
어쨌든 공식적인 사용 방법이 아님에는 틀림이 없다고 했던 것 같습니다.
정확히 하려면 그 어떤 (??) 공간의 “값”을 strcpy를 통해서
정식으로 복사하는 것이 바람직하다고 했던 것 같습니다.
저라면 저 위에 경우처럼 쓰지 않겠습니다.
오병현 octphial _at_ postech.ac.kr
Re^2: 저번에도 논란이 되었던 문제가 아닙니까?
메모리는 보통 code영역, data영역, heap, stack 이렇게
4 가지 종류로 나뉜다고 알고 있습니다.
char *p="string";
이렇게 코딩을 하면, "string"에 해당하는 부분은
code영역에 들어갑니다. (gcc -S 해 보시면 쉽게 알 수 있습니다.)
code영역에 들어가기 때문에 read only이고, 따라서
문자열을 고치려(즉 쓰려) 시도하면 segment fault를 냅니다.
char *p = (char*)malloc(sizeof(char)*N);
이렇게 해서 strcpy/memcpy등의 함수를 이용해 카피하는 것은
heap영역에 메모리를 잡기 때문에 read/write가 모두 가능하며
따라서 문자열을 마음대로 고칠 수 있습니다.
그 차이를 가지고 공식적인 사용이다 아니다 이렇게 말할 수는 없습니다.
그렇다면 printf("My name is %s",namestr) 이 코드도
"My name is %s"가 code 영역에 저장되게 되는데, "공식적으로"
잘못 사용하고 있는 것인가요?
char *p="something";
이렇게 하면 문자열을 마음대로 고칠 수 없다는 것을 아는 것으로
충분하며, readonly라는 것을 안다면 아무 문제 없습니다.
Re: 포인터와 배열....
아래에 지적하신 분들 말씀대로
문법상 오류는 없는 걸루 압니다.
p = "hi";
라고 하는 의미는 p가 문자열 "hi"의 주소를 가리키겠다는, 포인터 문법
에 전혀 문제없는 방식 아닌가요.
문자열 "hi"는 code영역에 올라가는데, 소스코드가 code영역에 쫘악 올라
갈때, 그때 저 "hi"라는 문자열이 소스코드안에 포함이 되겠죠. "hi"라는
문자열이 다른 메모리 영역에 따로 저장되는게 아니라서 포인터 p는 code
영역의 "hi"라는 문자열의 주소를 그대로 가리키게 됩니다. 물론,
readonly구요.
그리구, heap영역상에 메모리 잡아도 다른 메모리 할당에 의해 덮어져서
사라지거나 수정되는 경우는 없습니다. 잡아놓은 메모리 이상으로 사용하
지 않는다면요. 또, 엄밀히 말해서 배열을 쓴다고 해서 안전한 것도 아닙
니다. 배열은 해당함수의 stack 영역에 잡히는데 stack역시 지정 공간 이
상으로 쓰기가 가능하기 때문입니다. (stack overflow라고도 하죠)
엄밀히 말해서, 그건 프로그래머의 책임이죠.
Re^2: 추가질문) 포인터와 배열....
그건 틀리는 내용 입니다.
char *p[5]; -> 이건 포인터 5개를 저장할 포인터 배열이고.
char a[5][10] -> 이건 그냥 2차원 배열 입니다.
char a[5][10] -> char a[50] 이렇게 쓰는거랑 비슷합니다.
단지 편리하게 사용 할 수 있게 2차원을 쓰는거죠..
댓글 달기