200902022250
삽질 하나 (포인터 관련)
간단한 C 프로그램을 하나 짰다.<blockquote><div>void foo(char *s1, char *s2) {</div><div> …
</div><div> s1[j] = s1[i];
</div><div> …
</div><div>}</div><div>
</div><div>main() {</div><div> char *s1 = “blahblah”;
</div><div> foo(s1, “blah”);
</div><div>}</div><div></div></blockquote>문제는 실행을 시켰을 때 뻗어버렸다. (Unix였다면 Segmentation Fault였을)TCPL 예제에는 같은 식으로 함수 구현이 되어 있어서 내가 뭘 잘못했나 궁금했는데,main()에서 s1을 배열로 선언하면 정상적으로 동작하였다.잠시 구글링을 하다가 머리속에 스친 생각에 약간 바꾸어 보았다.<blockquote><div>main() {</div><div> char s1[] = “blahblah”;</div><div> char *s2 = &s1[0];</div><div> foo(s2, “blah”);
</div><div>}</div><div></div></blockquote>역시 문제 없이 잘 돌아간다.처음에는 포인터를 인자로 넘길 때 메모리 할당을 해야 하는건가? 싶었지만,문제는 그게 아니라 s1이 string constant를 가리키기 때문에 foo() 안에서 수정을 할 수 없는 것이다.간접적으로 알 수 있는 방법은,명시적으로 foo(const char *s1, char *s2)라고 선언하면 컴파일 에러가 뜨고,main에서 foo(“blahblah”, “blah”)로 호출하면 역시 뻗어버린다는 점.예전에도 비슷한 문제를 만났는데 그때는 원인을 못찾고 결국 메모리 할당을 했던 것 같다.<blockquote><div>char s1[] = “blahblah”;</div><div>char *s1 = “blahblah”;</div><div></div></blockquote>두 가지 선언은 겉보기는 같아도 의미는 다른 셈이다.초보적인 삽질을 한 것이 한심해서 나중에 같은 실수를 반복하지 않도록 적어둔다.
- 2009/02/02 22:50 에 작성