C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[690] [String] strcpy()야 놀자 - 펌
장성호 [nasilso] 8514 읽음    2007-07-26 13:42
http://cafe.naver.com/pplus 에서 퍼왔습니다.

AnsiString을 쓰면 strcpy를 쓸일이 별러 없겠지만...

strcpy뿐만 아니라 그밖에 시스템에 대해 여러가지 이해할수 있습니다..



----------------------------[펌글]----------------------------------

오늘은 strcpy() 함수랑 놀아 봅시다...

strcpy() 함수에 포인터를 잘못 사용하면 프로그램은 다운됩니다.

다음 대화를 통해 strcpy() 함수를 완벽하게 이해하여 봅시다.

 

딩동~~ strcpy() 님이 입장하셨습니다.

 

은철 : .. 너 이리와 봐...

strcpy : .. 저요? 긁적.. 긁적.. .

 

김은철 : ... . 너가 애덜 괴롭힌다며?

strcpy : 그런 적 없는데요...

 

김은철 : 그런데.. 애덜이 너만 보면 왜 떨어?

strcpy : 몰라~. 갸네들 혹시 떨녀 아녜요?

 

김은철 : 웃기셔... 애덜이 너를 고발했거든..

strcpy : 머라구요?

 

김은철 : 잘 가다가.. 너만 만나면.. 프로그램이 다운된다잖아.

strcpy : 저도 미치겠어요.. 그런 애들 때문에 저도 매일 운영 체제한테 혼나요. 아무 번지나 마구 접근한다고. .

 

김은철 : 어떤 상황이길래 그러는데?

strcpy : 보실래요? 애덜이 어떻게 저를 괴롭히나... 아래를 보세요. 아래처럼 하면 제가 혼나겠어요? 안혼나겠어요?

 

char* p = "사랑스러워";

char buf[10];

strcpy( buf, p );

 

김은철 : 무슨 문제라도?

strcpy : 사랑스러워가 10자리잖아요. 그리고 문자열이니까.. 끝에 널 문자가 추가되어야 하잖아요. 그런데 꼭 저런 애들이 있어요... buf[10]이잖아요. 그럼 제가 널 문자를 복사하다 보면, 다른 애들이 있는 곳까지 침범하게 되요... 이러면 다른 애들이 불평을 하죠.. 왜 자꾸 내 영역까지 오냐구... 내가 거기에 가고 싶냐구요. 애덜이 저렇게 복사하라고 하니까 어쩔 수 없이 복사하다 보면, 다른 애들이 있는 영역까지 침범해서 1바이트를 더 쓰게 되죠.

 

김은철 : 너가 알아서 10바이트만 복사하면 되잖아.

strcpy : 저는 그런 것 못해요.. 그냥 시키면 시키는 데로 할 뿐이죠.

 

김은철 : 단순하네.. 너가 알아서 하면.. 프로그램이 다운되는 그런 일은 발생하지 않을 텐데.

strcpy : 그럼 알아서 할 수 있게 저의 기능을 바꿔 주세요.

 

김은철 : ~.ㅠ 그럼, 저런 상황은 해결책이 전혀 없어?

strcpy : 있지요. buf[11]이라고 해주면 되지요.

 

김은철 : 그러면 해결돼?

strcpy : .. 그런데.. 만약 buf[11]이라고 한 후, 아래처럼 또 버퍼보다 많은 문자열을 복사하면 마찬가지로 다른 영역을 침범하게 되겠죠. 그러니까 복사할 버퍼보다 많은 버퍼를 선언해 주는 방법 외엔 해결 방법이 없어요.

 

strcpy( buf, "1234567890123" );

 

김은철 : 그럼 그건 그렇게 해결하면 되고, 다른 불만도 있던데 그건 어떻게 해결할꺼야?

strcpy : 뭔데요?

 

김은철 : 문자열을 복사하라고 했더니 프로그램이 다운되더래.

strcpy : 어떻게 했는데요?

 

김은철 : 다음 코드를 봐봐봐봐봐... 너가 저걸 안 해 준다며?

 

char* p;

strcpy( p, "밥 같이 먹을래 말래" );

 

strcpy : .. 안 해 주는 게 아니죠. 포인터가 가리키는 곳이 없잖아요. 포인터 p는 쓰레기 번지를 갖고 있네요. 잠시 기다려 봐요.. 제가 복사를 시도해 볼게요.

 

(운영체제한테)p는 쓰레기 번지인 74847483번지를 가리키고 있습니다. 이 곳에 "밥 같이 먹을래 말래"를 복사해 달라는 친구가 있는데요. 가능한가요?

운영체제 : 그 번지 그 놈꺼니?

 

strcpy : 몰라요.. 그 번지에다 복사해 달라네요.

운영 체제 : 잠시만... (메모리를 관리하는 팀에 조회 중...) 74847483번지를 접근하고 싶다는데 가능해? (.. 안돼? ? 다른 애가 사용 중이라고? 알떠) 안된데.

 

strcpy : 안돼요?

운영 체제 : .. 안돼. 허락되지 않은 번지에 침범한 것은 잘못된 거야.. 그 프로그램 다운시켜야겠다. 다른 프로그램의 안전을 위해서. 그렇게 알어.

 

strcpy : 나 죽어... 살려~~~~~~~ OTL

 

김은철 : ! 어디갔냐?

strcpy : 다운됐어요.. 그러니까.. 그런애들 때문에.. 저만 매일 혼나요. 복사할 수 있는 번지를 줘야 복사를 해 주죠.. 꼭 이상한 번지를 줘서.. 복사를 하려 하면 운영 체제가 잘못된 번지에 접근한다고 즉시 프로그램을 다운시켜 버리잖아요.

 

김은철 : 그럼 복사할 수 있는 번지를 주면 복사는 잘 해 주남?

strcpy : .. 당연하죠.

 

김은철 : 이건 그럼 왜 안 되는데? "왜왜왜"를 복사해 주란 말이지.

 

strcpy( "야야야", "왜왜왜" );

 

strcpy : .. 그 것도 갈 때마다 운영 체제한테 혼나는 거에요.

 

김은철 : ?

strcpy : "야야야"는 복사할 수 있는 버퍼가 아니라 문자열 상수잖아요. 문자열 상수 영역에다가 복사해 달라고 하면, 운영 체제한테 혼나요. 제가 부탁하면.. 바로 프로그램 다운돼요.

 

김은철 : 정말이야? 사실이야?

strcpy : . 운영 체제는 메모리라고 해서 다 복사해 주는 것이 아니에요. 메모리가 상수 영역으로 사용되고 있을 때는 값을 읽는 것은 허락해 주지만, 그 곳에 뭔가를 쓰면 안돼요.. 만약에 미술관에 가서 그림을 보다가 그 곳에 다른 그림을 그리면 어떻게 되겠어요?

 

김은철 : 경찰서로 가겠네.

strcpy : 그렇죠? 그러니까 쓰기가 허락되지 않은 곳에 뭔가를 쓰면 안돼요.

 

김은철 : 좋아.. 그럼 이건 왜 안 되는데? buf1이 복사할 수 있는 버퍼잖아.

 

char buf1[100];

char buf2[200];

strcpy( buf1, buf2 );

 

strcpy : .. 미쳐.. 미쳐.. buf1이 복사할 수 있는 버퍼는 맞는데요... buf2에 널 문자가 없네요. 저는 buf2를 복사하다가 널 문자를 만나면 복사를 그만하거든요. 그런데 buf2가 아무 초기화도 되지 않았으니까 쓰레기값만 꽉 차 있겠네요. 저는 문자열을 어디까지 복사할 지를 널 문자를 판단해서 알아내요. 그런데 문자열의 끝에 널 문자가 없으면, 어디까지 복사를 해야 할 지 알 수 없어요.. 저럴 경우 프로그램은 다운되지 않을 수는 있지만, 다른 영역을 침범해서 프로그램이 오동작하는 경우가 발생되죠.

 

김은철 : ~~~ 뭐가 그리 복잡하다냐? 대충.. 인생 머 있다구...

strcpy : 그렇죠.. 저런 것을 사용하는 애들이 포인터의 개념과 문자열의 개념이 부족하기 때문에 항상 문제아들로 분류되어 있어요. 위에 그런 애들 말고 다른 애들도 있어요. 다음을 봐봐봐요. 자기 딴에는 머리를 쓴다고 해 놨는데... 결국 p가 가리키는 곳이 문자열 상수 영역이기 때문에 또 프로그램 다운이에요.

 

char* p = "야야야";

strcpy( p, "왜왜왜" );

 

김은철 : 잠시만.. "야야야"가 문자열 상수야?

strcpy : .. 문자열 상수죠.

 

김은철 : 문자열 상수는 변수랑 다른가?

strcpy : 많이 다르죠... 문자열 상수는 컴파일이 되는 즉시 그들만의 고유한 메모리 영역에 생성되고, 문자열을 읽을 수만 있고, 그 곳을 다른 값으로 변경할 수 없도록 운영 체제가 관리해요. 그래서 문자열을 변경하려고 시도하면 바로 다운되요.

 

김은철 : 그럼.. 컴파일러가 미리 미리 컴파일 에러를 내면 편하겠네.

strcpy : 맞아요. 그러면 되는데 컴파일러는 단순해서 char*형인가만 조사하고 그 곳이 상수 영역인지 변수 영역인지는 조사해 주지 않아요. 제가 컴파일러를 만든다면 그런 것도 조사해 주겠어요. 그래야 프로그래머가 고생을 안하죠.

 

김은철 : 그러네.. 컴파일러가 바보네...

strcpy : 다음은 어떻게 될 것 같아요.. 한 번 맞춰보세요.

 

char buf[100];

char* p = buf;

strcpy( p, "야야야... " );

 

김은철 : p가 가리키는 곳이 buf이고, 거기에 복사를 하니까.. 잘 되겠네.

strcpy : 맞췄어요. 그럼 이거는요?

 

int  i;

strcpy( &i, "" );

 

김은철 : 그건 머데?

strcpy : ㅋㅋㅋ 모르겠어요? i 4바이트이니까 그 곳에 ""를 복사하라는 것이죠.

 

김은철 : 저것이 가능해?

strcpy : 그럼요.. 가능하죠.. 일반적으로 사용되지는 않지만 i도 메모리를 갖는 4바이트 버퍼니까 가능해요.

 

김은철 : 허허...

strcpy : 그럼 이거는요?

 

char  ch;

strcpy( &ch, "" );

 

김은철 : 그건 이상하네... ch1바이트이고, ""는 널 문자까지 3바이트이니까, 다른 변수들의 영역까지 침범 당하겠네.

strcpy : ㅋㅋㅋ 그렇죠? 그런데 아니에요. char형 변수는 그 크기가 1바이트인데, 실제로는 4바이트 공간을 할당해서 1바이트만 사용하는 거에요. 그러니까 저렇게 하면 잘 복사돼요. 다음과 같이 출력을 해 보면, "'가 잘 출력되는 것을 볼 수 있어요.

 

puts( ch );

 

김은철 : .. OTL이군.. 그건.. 그런 건 모르는 편이 좋겠네.

strcpy : 그렇기는 해요.. 하지만 변수와 메모리 크기 등의 관계를 잘 알아야 나중에 진정한 고수가 될 수 있어요.

 

김은철 : 그렇구나.. 초보인지 아닌지는 strcpy() 함수를 얼마나 이해하고 쓰는지를 보면 되겠네.

strcpy : 맞아요.. 저를 잘 아는 애들은 초보는 아니죠...

 

김은철 : 밤이 늦었네... 담에 또 보자고.

strcpy : .. good night ~

 

 
김태선 [cppbuilder]   2007-07-26 16:03 X
이미 C 시절에 다 다루어봤던 주제군요.
그래서 골수에 박혀 있다는...

아뭏튼 재미있는 대화군요. ^^;
슬.강슬기 [mydog21]   2008-02-20 17:11 X
이렇게 까지 자세한 사용법은 몰랐는데^^;;
재미있게 봤네요 ㅎㅎ

감사합니다

특히
int i;
strcpy( &i, "야야야야야") 이 대목에서 쓰러질뻔 했습니다. ㅎ

+ -

관련 글 리스트
690 [String] strcpy()야 놀자 - 펌 장성호 8514 2007/07/26
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.